cd-aichat 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/README.md +188 -0
  2. package/dist/ailogo.png +0 -0
  3. package/dist/cd-aichat.css +1 -0
  4. package/dist/cd-aichat.es.js +32223 -0
  5. package/dist/cd-aichat.umd.js +279 -0
  6. package/dist/index.css +1 -0
  7. package/package.json +61 -0
  8. package/src/ailogo.png +0 -0
  9. package/src/components/AiChat.test.js +538 -0
  10. package/src/components/AiChat.vue +2206 -0
  11. package/src/components/AiChatWidget.test.js +312 -0
  12. package/src/components/AiChatWidget.vue +963 -0
  13. package/src/components/BurnAfterReadDialog.test.js +121 -0
  14. package/src/components/BurnAfterReadDialog.vue +511 -0
  15. package/src/components/BurnAfterReadMessage.test.js +188 -0
  16. package/src/components/BurnAfterReadMessage.vue +193 -0
  17. package/src/components/BurnIndicator.test.js +101 -0
  18. package/src/components/BurnIndicator.vue +164 -0
  19. package/src/components/ChatWindow.vue +0 -0
  20. package/src/components/MentionList.vue +163 -0
  21. package/src/components/ResourceList.vue +194 -0
  22. package/src/components/RichTextEditor.vue +437 -0
  23. package/src/components/ScheduledSendDialog.vue +476 -0
  24. package/src/components/ScreenshotOverlay.vue +78 -0
  25. package/src/components/SendButtonGroup.test.js +174 -0
  26. package/src/components/SendButtonGroup.vue +166 -0
  27. package/src/components/UserDrawer.vue +0 -0
  28. package/src/components/screenshot/ScreenshotsBackground/getBoundsByPoints.ts +41 -0
  29. package/src/components/screenshot/ScreenshotsBackground/index.scss +27 -0
  30. package/src/components/screenshot/ScreenshotsBackground/index.tsx +145 -0
  31. package/src/components/screenshot/ScreenshotsButton/index.scss +29 -0
  32. package/src/components/screenshot/ScreenshotsButton/index.tsx +58 -0
  33. package/src/components/screenshot/ScreenshotsCanvas/getBoundsByPoints.ts +55 -0
  34. package/src/components/screenshot/ScreenshotsCanvas/getPoints.ts +60 -0
  35. package/src/components/screenshot/ScreenshotsCanvas/index.scss +84 -0
  36. package/src/components/screenshot/ScreenshotsCanvas/index.tsx +277 -0
  37. package/src/components/screenshot/ScreenshotsCanvas/isPointInDraw.ts +35 -0
  38. package/src/components/screenshot/ScreenshotsColor/index.scss +45 -0
  39. package/src/components/screenshot/ScreenshotsColor/index.tsx +39 -0
  40. package/src/components/screenshot/ScreenshotsContext.ts +56 -0
  41. package/src/components/screenshot/ScreenshotsMagnifier/index.scss +61 -0
  42. package/src/components/screenshot/ScreenshotsMagnifier/index.tsx +126 -0
  43. package/src/components/screenshot/ScreenshotsOperations/index.scss +25 -0
  44. package/src/components/screenshot/ScreenshotsOperations/index.tsx +118 -0
  45. package/src/components/screenshot/ScreenshotsOption/index.scss +50 -0
  46. package/src/components/screenshot/ScreenshotsOption/index.tsx +150 -0
  47. package/src/components/screenshot/ScreenshotsSize/index.scss +28 -0
  48. package/src/components/screenshot/ScreenshotsSize/index.tsx +41 -0
  49. package/src/components/screenshot/ScreenshotsSizeColor/index.scss +8 -0
  50. package/src/components/screenshot/ScreenshotsSizeColor/index.tsx +25 -0
  51. package/src/components/screenshot/ScreenshotsTextarea/calculateNodeSize.ts +117 -0
  52. package/src/components/screenshot/ScreenshotsTextarea/index.scss +19 -0
  53. package/src/components/screenshot/ScreenshotsTextarea/index.tsx +96 -0
  54. package/src/components/screenshot/composeImage.ts +57 -0
  55. package/src/components/screenshot/exports.ts +4 -0
  56. package/src/components/screenshot/hooks/useBounds.ts +35 -0
  57. package/src/components/screenshot/hooks/useCall.ts +17 -0
  58. package/src/components/screenshot/hooks/useCanvasContextRef.ts +8 -0
  59. package/src/components/screenshot/hooks/useCanvasMousedown.ts +13 -0
  60. package/src/components/screenshot/hooks/useCanvasMousemove.ts +13 -0
  61. package/src/components/screenshot/hooks/useCanvasMouseup.ts +13 -0
  62. package/src/components/screenshot/hooks/useCursor.ts +34 -0
  63. package/src/components/screenshot/hooks/useDispatcher.ts +8 -0
  64. package/src/components/screenshot/hooks/useDrawSelect.ts +16 -0
  65. package/src/components/screenshot/hooks/useEmiter.ts +61 -0
  66. package/src/components/screenshot/hooks/useHistory.ts +160 -0
  67. package/src/components/screenshot/hooks/useLang.ts +8 -0
  68. package/src/components/screenshot/hooks/useOperation.ts +37 -0
  69. package/src/components/screenshot/hooks/useReset.ts +26 -0
  70. package/src/components/screenshot/hooks/useStore.ts +8 -0
  71. package/src/components/screenshot/icons/iconfont.scss +88 -0
  72. package/src/components/screenshot/icons/iconfont.ttf +0 -0
  73. package/src/components/screenshot/icons/iconfont.woff +0 -0
  74. package/src/components/screenshot/icons/iconfont.woff2 +0 -0
  75. package/src/components/screenshot/index.tsx +169 -0
  76. package/src/components/screenshot/operations/Arrow/draw.ts +56 -0
  77. package/src/components/screenshot/operations/Arrow/index.tsx +193 -0
  78. package/src/components/screenshot/operations/Brush/draw.ts +45 -0
  79. package/src/components/screenshot/operations/Brush/index.tsx +169 -0
  80. package/src/components/screenshot/operations/Cancel/index.tsx +18 -0
  81. package/src/components/screenshot/operations/Ellipse/draw.ts +96 -0
  82. package/src/components/screenshot/operations/Ellipse/index.tsx +245 -0
  83. package/src/components/screenshot/operations/Mosaic/index.tsx +223 -0
  84. package/src/components/screenshot/operations/Ok/index.tsx +37 -0
  85. package/src/components/screenshot/operations/Pin/index.tsx +37 -0
  86. package/src/components/screenshot/operations/Rectangle/draw.ts +80 -0
  87. package/src/components/screenshot/operations/Rectangle/index.tsx +245 -0
  88. package/src/components/screenshot/operations/Redo/index.tsx +22 -0
  89. package/src/components/screenshot/operations/Save/index.tsx +37 -0
  90. package/src/components/screenshot/operations/Scan/index.tsx +46 -0
  91. package/src/components/screenshot/operations/Search/index.tsx +39 -0
  92. package/src/components/screenshot/operations/Text/index.tsx +307 -0
  93. package/src/components/screenshot/operations/Undo/index.tsx +22 -0
  94. package/src/components/screenshot/operations/index.ts +34 -0
  95. package/src/components/screenshot/operations/utils.ts +34 -0
  96. package/src/components/screenshot/screenshots.scss +13 -0
  97. package/src/components/screenshot/types.ts +53 -0
  98. package/src/components/screenshot/useGetLoadedImage.ts +29 -0
  99. package/src/components/screenshot/var.scss +107 -0
  100. package/src/components/screenshot/zh_CN.ts +37 -0
  101. package/src/emoji/100.gif +0 -0
  102. package/src/emoji/101.gif +0 -0
  103. package/src/emoji/102.gif +0 -0
  104. package/src/emoji/103.gif +0 -0
  105. package/src/emoji/104.gif +0 -0
  106. package/src/emoji/105.gif +0 -0
  107. package/src/emoji/106.gif +0 -0
  108. package/src/emoji/107.gif +0 -0
  109. package/src/emoji/108.gif +0 -0
  110. package/src/emoji/109.gif +0 -0
  111. package/src/emoji/110.gif +0 -0
  112. package/src/emoji/111.gif +0 -0
  113. package/src/emoji/112.gif +0 -0
  114. package/src/emoji/113.gif +0 -0
  115. package/src/emoji/114.gif +0 -0
  116. package/src/emoji/115.gif +0 -0
  117. package/src/emoji/116.gif +0 -0
  118. package/src/emoji/117.gif +0 -0
  119. package/src/emoji/118.gif +0 -0
  120. package/src/emoji/119.gif +0 -0
  121. package/src/emoji/120.gif +0 -0
  122. package/src/emoji/121.gif +0 -0
  123. package/src/emoji/122.gif +0 -0
  124. package/src/emoji/123.gif +0 -0
  125. package/src/emoji/124.gif +0 -0
  126. package/src/emoji/125.gif +0 -0
  127. package/src/emoji/126.gif +0 -0
  128. package/src/emoji/127.gif +0 -0
  129. package/src/emoji/128.gif +0 -0
  130. package/src/emoji/129.gif +0 -0
  131. package/src/emoji/130.gif +0 -0
  132. package/src/emoji/131.gif +0 -0
  133. package/src/emoji/132.gif +0 -0
  134. package/src/emoji/133.gif +0 -0
  135. package/src/emoji/134.gif +0 -0
  136. package/src/emoji/135.gif +0 -0
  137. package/src/emoji/136.gif +0 -0
  138. package/src/emoji/137.gif +0 -0
  139. package/src/emoji/138.gif +0 -0
  140. package/src/emoji/139.gif +0 -0
  141. package/src/emoji/140.gif +0 -0
  142. package/src/emoji/141.gif +0 -0
  143. package/src/emoji/142.gif +0 -0
  144. package/src/emoji/143.gif +0 -0
  145. package/src/emoji/144.gif +0 -0
  146. package/src/emoji/145.gif +0 -0
  147. package/src/emoji/146.gif +0 -0
  148. package/src/emoji/147.gif +0 -0
  149. package/src/emoji/148.gif +0 -0
  150. package/src/emoji/149.gif +0 -0
  151. package/src/emoji/150.gif +0 -0
  152. package/src/emoji/151.gif +0 -0
  153. package/src/emoji/152.gif +0 -0
  154. package/src/emoji/153.gif +0 -0
  155. package/src/emoji/154.gif +0 -0
  156. package/src/emoji/155.gif +0 -0
  157. package/src/emoji/156.gif +0 -0
  158. package/src/emoji/157.gif +0 -0
  159. package/src/emoji/158.gif +0 -0
  160. package/src/emoji/159.gif +0 -0
  161. package/src/emoji/160.gif +0 -0
  162. package/src/emoji/161.gif +0 -0
  163. package/src/emoji/162.gif +0 -0
  164. package/src/emoji/163.gif +0 -0
  165. package/src/emoji/164.gif +0 -0
  166. package/src/emoji/165.gif +0 -0
  167. package/src/emoji/166.gif +0 -0
  168. package/src/emoji/167.gif +0 -0
  169. package/src/emoji/168.gif +0 -0
  170. package/src/emoji/169.gif +0 -0
  171. package/src/emoji/170.gif +0 -0
  172. package/src/emoji/171.gif +0 -0
  173. package/src/emoji/172.gif +0 -0
  174. package/src/emoji/173.gif +0 -0
  175. package/src/emoji/174.gif +0 -0
  176. package/src/emoji/175.gif +0 -0
  177. package/src/emoji/176.gif +0 -0
  178. package/src/emoji/177.gif +0 -0
  179. package/src/emoji/178.gif +0 -0
  180. package/src/emoji/179.gif +0 -0
  181. package/src/emoji/180.gif +0 -0
  182. package/src/emoji/181.gif +0 -0
  183. package/src/emoji/182.gif +0 -0
  184. package/src/emoji/183.gif +0 -0
  185. package/src/emoji/184.gif +0 -0
  186. package/src/emoji/185.gif +0 -0
  187. package/src/emoji/186.gif +0 -0
  188. package/src/emoji/187.gif +0 -0
  189. package/src/emoji/188.gif +0 -0
  190. package/src/emoji/189.gif +0 -0
  191. package/src/emoji/190.gif +0 -0
  192. package/src/emoji/191.gif +0 -0
  193. package/src/emoji/192.gif +0 -0
  194. package/src/emoji/193.gif +0 -0
  195. package/src/emoji/194.gif +0 -0
  196. package/src/emoji/195.gif +0 -0
  197. package/src/emoji/196.gif +0 -0
  198. package/src/emoji/197.gif +0 -0
  199. package/src/emoji/198.gif +0 -0
  200. package/src/emoji/199.gif +0 -0
  201. package/src/emoji/200.png +0 -0
  202. package/src/emoji/201.png +0 -0
  203. package/src/emoji/202.png +0 -0
  204. package/src/emoji/203.png +0 -0
  205. package/src/emoji/204.png +0 -0
  206. package/src/emoji/205.png +0 -0
  207. package/src/emoji/206.png +0 -0
  208. package/src/emoji/207.png +0 -0
  209. package/src/emoji/208.png +0 -0
  210. package/src/emoji/209.png +0 -0
  211. package/src/emoji/210.png +0 -0
  212. package/src/emoji/211.png +0 -0
  213. package/src/emoji/212.png +0 -0
  214. package/src/emoji/213.png +0 -0
  215. package/src/emoji/214.png +0 -0
  216. package/src/emoji/215.png +0 -0
  217. package/src/emoji/216.png +0 -0
  218. package/src/emoji/217.png +0 -0
  219. package/src/emoji/218.png +0 -0
  220. package/src/emoji/219.png +0 -0
  221. package/src/emoji2/101--Streamline-The-Team.png +0 -0
  222. package/src/emoji2/128--Streamline-The-Team.png +0 -0
  223. package/src/emoji2/134--Streamline-The-Team.png +0 -0
  224. package/src/emoji2/173--Streamline-The-Team.png +0 -0
  225. package/src/emoji2/Airplane--Streamline-Emoji.svg +24 -0
  226. package/src/emoji2/Alien--Streamline-Emoji.svg +21 -0
  227. package/src/emoji2/Amazed-Face--Streamline-Emoji.svg +16 -0
  228. package/src/emoji2/Amusing-Face--Streamline-Emoji.svg +20 -0
  229. package/src/emoji2/Anguished-Face--Streamline-Emoji.svg +19 -0
  230. package/src/emoji2/Anxious-Face--Streamline-Emoji.svg +17 -0
  231. package/src/emoji2/Astonished-Face--Streamline-Emoji.svg +20 -0
  232. package/src/emoji2/Backhand-Index-Pointing-Down-1--Streamline-Emoji.svg +12 -0
  233. package/src/emoji2/Backhand-Index-Pointing-Left-1--Streamline-Emoji.svg +13 -0
  234. package/src/emoji2/Backhand-Index-Pointing-Right-1--Streamline-Emoji.svg +13 -0
  235. package/src/emoji2/Backhand-Index-Pointing-Up-1--Streamline-Emoji.svg +14 -0
  236. package/src/emoji2/Bar-Chart--Streamline-Emoji.svg +22 -0
  237. package/src/emoji2/Beaming-Face-With-Smiling-Eyes--Streamline-Emoji.svg +20 -0
  238. package/src/emoji2/Boy-1--Streamline-Emoji.svg +17 -0
  239. package/src/emoji2/Boy-2--Streamline-Emoji.svg +17 -0
  240. package/src/emoji2/Boy-3--Streamline-Emoji.svg +17 -0
  241. package/src/emoji2/Broken-Heart--Streamline-Emoji.svg +12 -0
  242. package/src/emoji2/Clapping-Hands-1--Streamline-Emoji.svg +23 -0
  243. package/src/emoji2/Clinking-Glasses-2--Streamline-Emoji.svg +43 -0
  244. package/src/emoji2/Confounded-Face--Streamline-Emoji.svg +17 -0
  245. package/src/emoji2/Confused-Face--Streamline-Emoji.svg +15 -0
  246. package/src/emoji2/Construction-Worker--Streamline-Emoji.svg +21 -0
  247. package/src/emoji2/Couple-With-Heart-Woman-Man-1--Streamline-Emoji.svg +40 -0
  248. package/src/emoji2/Couple-With-Heart-Woman-Man-2--Streamline-Emoji.svg +40 -0
  249. package/src/emoji2/Cowboy-Hat-Face--Streamline-Emoji.svg +22 -0
  250. package/src/emoji2/Crazy-Face--Streamline-Emoji.svg +25 -0
  251. package/src/emoji2/Crossed-Fingers-1--Streamline-Emoji.svg +25 -0
  252. package/src/emoji2/Crown--Streamline-Emoji.svg +35 -0
  253. package/src/emoji2/Crying-Face--Streamline-Emoji.svg +26 -0
  254. package/src/emoji2/Delivery-Truck--Streamline-Emoji.svg +31 -0
  255. package/src/emoji2/Determined-Face--Streamline-Emoji.svg +25 -0
  256. package/src/emoji2/Disappointed-Face--Streamline-Emoji.svg +15 -0
  257. package/src/emoji2/Dizzy-Face--Streamline-Emoji.svg +20 -0
  258. package/src/emoji2/Downcast-Face-With-Sweat--Streamline-Emoji.svg +18 -0
  259. package/src/emoji2/Drooling-Face-1--Streamline-Emoji.svg +19 -0
  260. package/src/emoji2/Drooling-Face-2--Streamline-Emoji.svg +18 -0
  261. package/src/emoji2/Ear--Streamline-Emoji.svg +14 -0
  262. package/src/emoji2/Exclamation-Mark--Streamline-Emoji.svg +12 -0
  263. package/src/emoji2/Exploding-Head--Streamline-Emoji.svg +24 -0
  264. package/src/emoji2/Expressionless-Face--Streamline-Emoji.svg +15 -0
  265. package/src/emoji2/Face-Blowing-A-Kiss--Streamline-Emoji.svg +18 -0
  266. package/src/emoji2/Face-Savoring-Food--Streamline-Emoji.svg +18 -0
  267. package/src/emoji2/Face-Screaming-In-Fear--Streamline-Emoji.svg +18 -0
  268. package/src/emoji2/Face-Vomiting--Streamline-Emoji.svg +28 -0
  269. package/src/emoji2/Face-With-Head-Bandage--Streamline-Emoji.svg +25 -0
  270. package/src/emoji2/Face-With-Medical-Mask--Streamline-Emoji.svg +23 -0
  271. package/src/emoji2/Face-With-Monocle--Streamline-Emoji.svg +26 -0
  272. package/src/emoji2/Face-With-Raised-Eyebrow--Streamline-Emoji.svg +17 -0
  273. package/src/emoji2/Face-With-Rolling-Eyes--Streamline-Emoji.svg +17 -0
  274. package/src/emoji2/Face-With-Steam-From-Nose--Streamline-Emoji.svg +19 -0
  275. package/src/emoji2/Face-With-Symbols-On-Mouth--Streamline-Emoji.svg +22 -0
  276. package/src/emoji2/Face-With-Tears-Of-Joy--Streamline-Emoji.svg +34 -0
  277. package/src/emoji2/Face-With-Thermometer--Streamline-Emoji.svg +31 -0
  278. package/src/emoji2/Face-With-Tongue--Streamline-Emoji.svg +18 -0
  279. package/src/emoji2/Face-Without-Mouth--Streamline-Emoji.svg +14 -0
  280. package/src/emoji2/Fearful-Face--Streamline-Emoji.svg +18 -0
  281. package/src/emoji2/Flexed-Biceps-1--Streamline-Emoji.svg +13 -0
  282. package/src/emoji2/Flushed-Face--Streamline-Emoji.svg +19 -0
  283. package/src/emoji2/Folded-Hands-1--Streamline-Emoji.svg +29 -0
  284. package/src/emoji2/Frowning-Face--Streamline-Emoji.svg +15 -0
  285. package/src/emoji2/Fuel-Pump--Streamline-Emoji.svg +30 -0
  286. package/src/emoji2/Girl-1--Streamline-Emoji.svg +23 -0
  287. package/src/emoji2/Glasses-1--Streamline-Emoji.svg +27 -0
  288. package/src/emoji2/Grimacing-Face--Streamline-Emoji.svg +19 -0
  289. package/src/emoji2/Grinning-Cat-Face--Streamline-Emoji.svg +32 -0
  290. package/src/emoji2/Grinning-Face--Streamline-Emoji.svg +16 -0
  291. package/src/emoji2/Grinning-Face-With-Sweat--Streamline-Emoji.svg +19 -0
  292. package/src/emoji2/Grinning-Squinting-Face--Streamline-Emoji.svg +16 -0
  293. package/src/emoji2/Hand-With-Fingers-Splayed-1--Streamline-Emoji.svg +14 -0
  294. package/src/emoji2/Heart-Suit--Streamline-Emoji.svg +9 -0
  295. package/src/emoji2/Hushed-Face-1--Streamline-Emoji.svg +17 -0
  296. package/src/emoji2/Hushed-Face-2--Streamline-Emoji.svg +15 -0
  297. package/src/emoji2/Index-Pointing-Up-1--Streamline-Emoji.svg +17 -0
  298. package/src/emoji2/Kissing-Face-With-Closed-Eyes--Streamline-Emoji.svg +18 -0
  299. package/src/emoji2/Loudly-Crying-Face--Streamline-Emoji.svg +16 -0
  300. package/src/emoji2/Lying-Face--Streamline-Emoji.svg +15 -0
  301. package/src/emoji2/Man-1--Streamline-Emoji.svg +17 -0
  302. package/src/emoji2/Man-Facepalming-1--Streamline-Emoji.svg +21 -0
  303. package/src/emoji2/Man-Gesturing-No-1--Streamline-Emoji.svg +34 -0
  304. package/src/emoji2/Man-Gesturing-Ok-1--Streamline-Emoji.svg +25 -0
  305. package/src/emoji2/Man-Health-Worker-1--Streamline-Emoji.svg +41 -0
  306. package/src/emoji2/Man-Raising-Hand-1--Streamline-Emoji.svg +26 -0
  307. package/src/emoji2/Man-Shrugging-1--Streamline-Emoji.svg +31 -0
  308. package/src/emoji2/Money-Mouth-Face-2--Streamline-Emoji.svg +30 -0
  309. package/src/emoji2/Mouth--Streamline-Emoji.svg +12 -0
  310. package/src/emoji2/Nauseated-Face-2--Streamline-Emoji.svg +19 -0
  311. package/src/emoji2/Neutral-Face--Streamline-Emoji.svg +15 -0
  312. package/src/emoji2/Ok-Hand-1--Streamline-Emoji.svg +14 -0
  313. package/src/emoji2/Old-Man-1--Streamline-Emoji.svg +27 -0
  314. package/src/emoji2/Old-Woman-1--Streamline-Emoji.svg +23 -0
  315. package/src/emoji2/Oncoming-Fist-1--Streamline-Emoji.svg +15 -0
  316. package/src/emoji2/Person-Wearing-Turban-2--Streamline-Emoji.svg +20 -0
  317. package/src/emoji2/Pile-Of-Poo--Streamline-Emoji.svg +15 -0
  318. package/src/emoji2/Police-Car-Light--Streamline-Emoji.svg +26 -0
  319. package/src/emoji2/Rocket--Streamline-Emoji.svg +32 -0
  320. package/src/emoji2/Sailboat--Streamline-Emoji.svg +18 -0
  321. package/src/emoji2/Shaved-Ice--Streamline-Emoji.svg +21 -0
  322. package/src/emoji2/Shortcake-2--Streamline-Emoji.svg +18 -0
  323. package/src/emoji2/Shushing-Face--Streamline-Emoji.svg +21 -0
  324. package/src/emoji2/Sign-Of-The-Horns-1--Streamline-Emoji.svg +19 -0
  325. package/src/emoji2/Sleeping-Face--Streamline-Emoji.svg +21 -0
  326. package/src/emoji2/Slightly-Smiling-Face--Streamline-Emoji.svg +15 -0
  327. package/src/emoji2/Smiling-Face-With-Halo--Streamline-Emoji.svg +20 -0
  328. package/src/emoji2/Smiling-Face-With-Heart-Eyes--Streamline-Emoji.svg +21 -0
  329. package/src/emoji2/Smirking-Face--Streamline-Emoji.svg +17 -0
  330. package/src/emoji2/Sun-With-Face--Streamline-Emoji.svg +24 -0
  331. package/src/emoji2/Thumbs-Down-1--Streamline-Emoji.svg +20 -0
  332. package/src/emoji2/Thumbs-Up-1--Streamline-Emoji.svg +19 -0
  333. package/src/emoji2/Winking-Face--Streamline-Emoji.svg +18 -0
  334. package/src/emoji2/Woman-Gesturing-No-1--Streamline-Emoji.svg +34 -0
  335. package/src/emoji2/Woman-Gesturing-Ok-2--Streamline-Emoji.svg +25 -0
  336. package/src/emoji2/Woman-Raising-Hand-1--Streamline-Emoji.svg +26 -0
  337. package/src/emoji2/Womans-Sandal--Streamline-Emoji.svg +13 -0
  338. package/src/emoji2/Worried-Face--Streamline-Emoji.svg +17 -0
  339. package/src/emoji2/Writing-Hand-1--Streamline-Emoji.svg +17 -0
  340. package/src/emoji2/Zipper-Mouth-Face--Streamline-Emoji.svg +21 -0
  341. package/src/index.js +19 -0
  342. package/src/services/burn-after-read-service.js +313 -0
  343. package/src/services/burn-after-read-service.test.js +325 -0
  344. package/src/services/dify-api.js +338 -0
  345. package/src/services/dify-api.test.js +376 -0
  346. package/src/services/scheduled-send-service.js +311 -0
  347. package/src/services/scheduled-send-service.test.js +317 -0
  348. package/src/styles/index.css +2368 -0
  349. package/src/utils/emoji.js +125 -0
  350. package/src/utils/emojiData.js +267 -0
  351. package/src/utils/eventEmitter.js +114 -0
  352. package/src/utils/state.js +224 -0
  353. package/src/utils/state.test.js +198 -0
  354. package/src/utils/storage.js +122 -0
  355. package/src/utils/storage.test.js +162 -0
  356. package/src/utils/validation.js +249 -0
@@ -0,0 +1,376 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import DifyApiService from './dify-api.js';
3
+ import axios from 'axios';
4
+
5
+ // Mock axios
6
+ vi.mock('axios');
7
+
8
+ describe('DifyApiService', () => {
9
+ let mockAxiosInstance;
10
+
11
+ beforeEach(() => {
12
+ // 重置所有 mocks
13
+ vi.clearAllMocks();
14
+
15
+ // 创建 mock axios 实例
16
+ mockAxiosInstance = {
17
+ post: vi.fn(),
18
+ get: vi.fn()
19
+ };
20
+
21
+ axios.create.mockReturnValue(mockAxiosInstance);
22
+ });
23
+
24
+ describe('构造函数', () => {
25
+ it('应该支持旧的构造函数签名 (baseURL, agentId)', () => {
26
+ const service = new DifyApiService('https://api.dify.ai/v1', 'agent-001');
27
+
28
+ expect(service.baseURL).toBe('https://api.dify.ai/v1');
29
+ expect(service.agentId).toBe('agent-001');
30
+ expect(service.platform).toBe('');
31
+ expect(service.scene).toBe('');
32
+ });
33
+
34
+ it('应该支持新的配置对象签名', () => {
35
+ const config = {
36
+ url: 'https://api.dify.ai/v1',
37
+ agentId: 'agent-001',
38
+ platform: 'report',
39
+ scene: 'data-analysis',
40
+ knowledgeBase: {
41
+ type: 'json',
42
+ data: { test: 'data' }
43
+ },
44
+ inputVariables: {
45
+ userRole: 'analyst'
46
+ }
47
+ };
48
+
49
+ const service = new DifyApiService(config);
50
+
51
+ expect(service.baseURL).toBe('https://api.dify.ai/v1');
52
+ expect(service.agentId).toBe('agent-001');
53
+ expect(service.platform).toBe('report');
54
+ expect(service.scene).toBe('data-analysis');
55
+ expect(service.knowledgeBase).toEqual(config.knowledgeBase);
56
+ expect(service.inputVariables).toEqual(config.inputVariables);
57
+ });
58
+
59
+ it('应该在缺少 URL 时抛出错误', () => {
60
+ expect(() => {
61
+ new DifyApiService({ agentId: 'agent-001' });
62
+ }).toThrow('API URL is required');
63
+ });
64
+
65
+ it('应该在缺少 agentId 时抛出错误', () => {
66
+ expect(() => {
67
+ new DifyApiService({ url: 'https://api.dify.ai/v1' });
68
+ }).toThrow('Agent ID is required');
69
+ });
70
+
71
+ it('应该设置默认的会话配置', () => {
72
+ const service = new DifyApiService({
73
+ url: 'https://api.dify.ai/v1',
74
+ agentId: 'agent-001'
75
+ });
76
+
77
+ expect(service.conversationConfig).toEqual({
78
+ id: '',
79
+ autoCreate: true,
80
+ timeout: 1800000
81
+ });
82
+ });
83
+
84
+ it('应该设置默认的响应配置', () => {
85
+ const service = new DifyApiService({
86
+ url: 'https://api.dify.ai/v1',
87
+ agentId: 'agent-001'
88
+ });
89
+
90
+ expect(service.responseConfig).toEqual({
91
+ mode: 'blocking',
92
+ timeout: 30000,
93
+ maxRetries: 3
94
+ });
95
+ });
96
+ });
97
+
98
+ describe('updateConfig', () => {
99
+ let service;
100
+
101
+ beforeEach(() => {
102
+ service = new DifyApiService({
103
+ url: 'https://api.dify.ai/v1',
104
+ agentId: 'agent-001'
105
+ });
106
+ });
107
+
108
+ it('应该更新 URL', () => {
109
+ service.updateConfig({ url: 'https://new-api.dify.ai/v1' });
110
+ expect(service.baseURL).toBe('https://new-api.dify.ai/v1');
111
+ });
112
+
113
+ it('应该更新 agentId', () => {
114
+ service.updateConfig({ agentId: 'agent-002' });
115
+ expect(service.agentId).toBe('agent-002');
116
+ });
117
+
118
+ it('应该更新 platform', () => {
119
+ service.updateConfig({ platform: 'lowcode' });
120
+ expect(service.platform).toBe('lowcode');
121
+ });
122
+
123
+ it('应该更新 scene', () => {
124
+ service.updateConfig({ scene: 'form-builder' });
125
+ expect(service.scene).toBe('form-builder');
126
+ });
127
+
128
+ it('应该更新 knowledgeBase', () => {
129
+ const kb = { type: 'json', data: { test: 'data' } };
130
+ service.updateConfig({ knowledgeBase: kb });
131
+ expect(service.knowledgeBase).toEqual(kb);
132
+ });
133
+
134
+ it('应该更新 inputVariables', () => {
135
+ const vars = { userRole: 'admin' };
136
+ service.updateConfig({ inputVariables: vars });
137
+ expect(service.inputVariables).toEqual(vars);
138
+ });
139
+
140
+ it('应该重新创建 axios 客户端', () => {
141
+ const createCallsBefore = axios.create.mock.calls.length;
142
+ service.updateConfig({ url: 'https://new-api.dify.ai/v1' });
143
+ expect(axios.create.mock.calls.length).toBe(createCallsBefore + 1);
144
+ });
145
+ });
146
+
147
+ describe('_buildInputVariables', () => {
148
+ it('应该合并配置的和运行时的输入变量', () => {
149
+ const service = new DifyApiService({
150
+ url: 'https://api.dify.ai/v1',
151
+ agentId: 'agent-001',
152
+ inputVariables: {
153
+ configVar: 'config',
154
+ shared: 'fromConfig'
155
+ }
156
+ });
157
+
158
+ const result = service._buildInputVariables({
159
+ runtimeVar: 'runtime',
160
+ shared: 'fromRuntime'
161
+ });
162
+
163
+ expect(result).toEqual({
164
+ configVar: 'config',
165
+ runtimeVar: 'runtime',
166
+ shared: 'fromRuntime' // 运行时变量应该覆盖配置变量
167
+ });
168
+ });
169
+
170
+ it('应该添加平台信息到输入变量', () => {
171
+ const service = new DifyApiService({
172
+ url: 'https://api.dify.ai/v1',
173
+ agentId: 'agent-001',
174
+ platform: 'report'
175
+ });
176
+
177
+ const result = service._buildInputVariables();
178
+
179
+ expect(result._platform).toBe('report');
180
+ });
181
+
182
+ it('应该添加场景信息到输入变量', () => {
183
+ const service = new DifyApiService({
184
+ url: 'https://api.dify.ai/v1',
185
+ agentId: 'agent-001',
186
+ scene: 'data-analysis'
187
+ });
188
+
189
+ const result = service._buildInputVariables();
190
+
191
+ expect(result._scene).toBe('data-analysis');
192
+ });
193
+
194
+ it('应该添加知识库数据到输入变量', () => {
195
+ const kbData = { reports: ['sales', 'finance'] };
196
+ const service = new DifyApiService({
197
+ url: 'https://api.dify.ai/v1',
198
+ agentId: 'agent-001',
199
+ knowledgeBase: {
200
+ type: 'json',
201
+ data: kbData
202
+ }
203
+ });
204
+
205
+ const result = service._buildInputVariables();
206
+
207
+ expect(result._knowledgeBase).toEqual(kbData);
208
+ });
209
+ });
210
+
211
+ describe('sendMessage', () => {
212
+ let service;
213
+
214
+ beforeEach(() => {
215
+ service = new DifyApiService({
216
+ url: 'https://api.dify.ai/v1',
217
+ agentId: 'agent-001',
218
+ platform: 'report',
219
+ scene: 'data-analysis'
220
+ });
221
+
222
+ mockAxiosInstance.post.mockResolvedValue({
223
+ data: {
224
+ answer: 'AI response',
225
+ conversation_id: 'conv-001',
226
+ message_id: 'msg-001',
227
+ created_at: Date.now()
228
+ }
229
+ });
230
+ });
231
+
232
+ it('应该发送消息到 Dify API', async () => {
233
+ await service.sendMessage('Hello', 'user-001');
234
+
235
+ expect(mockAxiosInstance.post).toHaveBeenCalledWith(
236
+ '/chat-messages',
237
+ expect.objectContaining({
238
+ query: 'Hello',
239
+ user: 'user-001',
240
+ response_mode: 'blocking'
241
+ }),
242
+ expect.objectContaining({
243
+ headers: {
244
+ 'X-Agent-Id': 'agent-001'
245
+ }
246
+ })
247
+ );
248
+ });
249
+
250
+ it('应该包含平台和场景信息在输入变量中', async () => {
251
+ await service.sendMessage('Hello', 'user-001');
252
+
253
+ const callArgs = mockAxiosInstance.post.mock.calls[0][1];
254
+ expect(callArgs.inputs._platform).toBe('report');
255
+ expect(callArgs.inputs._scene).toBe('data-analysis');
256
+ });
257
+
258
+ it('应该合并运行时输入变量', async () => {
259
+ await service.sendMessage('Hello', 'user-001', {
260
+ inputVariables: {
261
+ currentPage: 'dashboard'
262
+ }
263
+ });
264
+
265
+ const callArgs = mockAxiosInstance.post.mock.calls[0][1];
266
+ expect(callArgs.inputs.currentPage).toBe('dashboard');
267
+ });
268
+
269
+ it('应该使用传入的会话 ID', async () => {
270
+ await service.sendMessage('Hello', 'user-001', {
271
+ conversationId: 'conv-existing'
272
+ });
273
+
274
+ const callArgs = mockAxiosInstance.post.mock.calls[0][1];
275
+ expect(callArgs.conversation_id).toBe('conv-existing');
276
+ });
277
+
278
+ it('应该更新当前会话 ID', async () => {
279
+ await service.sendMessage('Hello', 'user-001');
280
+
281
+ expect(service.currentConversationId).toBe('conv-001');
282
+ expect(service.conversationCreatedAt).toBeTruthy();
283
+ });
284
+
285
+ it('应该在缺少 userId 时抛出错误', async () => {
286
+ await expect(service.sendMessage('Hello', '')).rejects.toThrow('User ID is required');
287
+ });
288
+
289
+ it('应该处理 API 错误', async () => {
290
+ mockAxiosInstance.post.mockRejectedValue(new Error('API Error'));
291
+
292
+ await expect(service.sendMessage('Hello', 'user-001')).rejects.toThrow('API Error');
293
+ });
294
+ });
295
+
296
+ describe('会话管理', () => {
297
+ let service;
298
+
299
+ beforeEach(() => {
300
+ service = new DifyApiService({
301
+ url: 'https://api.dify.ai/v1',
302
+ agentId: 'agent-001'
303
+ });
304
+ });
305
+
306
+ it('createConversation 应该重置会话状态', async () => {
307
+ service.currentConversationId = 'conv-001';
308
+ service.conversationCreatedAt = Date.now();
309
+
310
+ await service.createConversation('user-001');
311
+
312
+ expect(service.currentConversationId).toBe('');
313
+ expect(service.conversationCreatedAt).toBeNull();
314
+ });
315
+
316
+ it('getConversation 应该返回当前会话信息', async () => {
317
+ service.currentConversationId = 'conv-001';
318
+ service.conversationCreatedAt = 123456789;
319
+ service.platform = 'report';
320
+ service.scene = 'data-analysis';
321
+
322
+ const result = await service.getConversation('conv-001');
323
+
324
+ expect(result).toEqual({
325
+ id: 'conv-001',
326
+ createdAt: 123456789,
327
+ platform: 'report',
328
+ scene: 'data-analysis'
329
+ });
330
+ });
331
+
332
+ it('isConversationExpired 应该检测会话超时', () => {
333
+ service.conversationCreatedAt = Date.now() - 2000000; // 超过 30 分钟
334
+
335
+ expect(service.isConversationExpired()).toBe(true);
336
+ });
337
+
338
+ it('isConversationExpired 应该在会话未超时时返回 false', () => {
339
+ service.conversationCreatedAt = Date.now() - 60000; // 1 分钟前
340
+
341
+ expect(service.isConversationExpired()).toBe(false);
342
+ });
343
+
344
+ it('resetConversation 应该重置会话状态', () => {
345
+ service.currentConversationId = 'conv-001';
346
+ service.conversationCreatedAt = Date.now();
347
+
348
+ service.resetConversation();
349
+
350
+ expect(service.currentConversationId).toBe('');
351
+ expect(service.conversationCreatedAt).toBeNull();
352
+ });
353
+ });
354
+
355
+ describe('知识库管理', () => {
356
+ let service;
357
+
358
+ beforeEach(() => {
359
+ service = new DifyApiService({
360
+ url: 'https://api.dify.ai/v1',
361
+ agentId: 'agent-001'
362
+ });
363
+ });
364
+
365
+ it('updateKnowledgeBase 应该更新知识库', () => {
366
+ const kb = {
367
+ type: 'json',
368
+ data: { test: 'data' }
369
+ };
370
+
371
+ service.updateKnowledgeBase(kb);
372
+
373
+ expect(service.knowledgeBase).toEqual(kb);
374
+ });
375
+ });
376
+ });
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Scheduled Send Service
3
+ * 管理延时发送消息的调度和执行
4
+ */
5
+
6
+ import { ref } from 'vue';
7
+ import { saveToStorage, loadFromStorage } from '../utils/storage';
8
+ import { validateScheduledTime } from '../utils/validation';
9
+
10
+ const STORAGE_KEY = 'scheduled-messages';
11
+
12
+ /**
13
+ * 创建延时发送服务实例
14
+ */
15
+ export const createScheduledSendService = () => {
16
+ const scheduledMessages = ref([]);
17
+ const timers = ref({});
18
+ const listeners = ref({});
19
+
20
+ /**
21
+ * 初始化服务,加载已保存的消息
22
+ */
23
+ const initialize = () => {
24
+ const saved = loadFromStorage(STORAGE_KEY, []);
25
+ scheduledMessages.value = saved.map(msg => ({
26
+ ...msg,
27
+ scheduledTime: new Date(msg.scheduledTime)
28
+ }));
29
+
30
+ // 为每条消息设置定时器
31
+ scheduledMessages.value.forEach(msg => {
32
+ scheduleMessage(msg);
33
+ });
34
+ };
35
+
36
+ /**
37
+ * 添加延时消息
38
+ * @param {Object} message - 消息对象
39
+ * @param {string} message.content - 消息内容
40
+ * @param {Date} message.scheduledTime - 预定发送时间
41
+ * @returns {Object} 添加的消息对象
42
+ */
43
+ const addMessage = (message) => {
44
+ // 验证时间
45
+ const validation = validateScheduledTime(message.scheduledTime);
46
+ if (!validation.valid) {
47
+ throw new Error(validation.errors[0]);
48
+ }
49
+
50
+ const scheduledMessage = {
51
+ id: generateMessageId(),
52
+ content: message.content,
53
+ scheduledTime: message.scheduledTime,
54
+ createdAt: new Date(),
55
+ status: 'pending' // pending | sent | cancelled
56
+ };
57
+
58
+ scheduledMessages.value.push(scheduledMessage);
59
+ saveMessages();
60
+ scheduleMessage(scheduledMessage);
61
+
62
+ // 触发事件
63
+ emit('message-added', scheduledMessage);
64
+
65
+ return scheduledMessage;
66
+ };
67
+
68
+ /**
69
+ * 更新延时消息
70
+ * @param {string} messageId - 消息ID
71
+ * @param {Object} updates - 更新内容
72
+ * @returns {Object} 更新后的消息对象
73
+ */
74
+ const updateMessage = (messageId, updates) => {
75
+ const index = scheduledMessages.value.findIndex(m => m.id === messageId);
76
+ if (index === -1) {
77
+ throw new Error('消息不存在');
78
+ }
79
+
80
+ const message = scheduledMessages.value[index];
81
+
82
+ // 如果更新了时间,需要重新调度
83
+ if (updates.scheduledTime) {
84
+ const validation = validateScheduledTime(updates.scheduledTime);
85
+ if (!validation.valid) {
86
+ throw new Error(validation.errors[0]);
87
+ }
88
+
89
+ // 取消旧的定时器
90
+ if (timers.value[messageId]) {
91
+ clearTimeout(timers.value[messageId]);
92
+ delete timers.value[messageId];
93
+ }
94
+ }
95
+
96
+ // 更新消息
97
+ Object.assign(message, updates);
98
+ saveMessages();
99
+
100
+ // 重新调度
101
+ if (updates.scheduledTime) {
102
+ scheduleMessage(message);
103
+ }
104
+
105
+ // 触发事件
106
+ emit('message-updated', message);
107
+
108
+ return message;
109
+ };
110
+
111
+ /**
112
+ * 取消延时消息
113
+ * @param {string} messageId - 消息ID
114
+ */
115
+ const cancelMessage = (messageId) => {
116
+ const index = scheduledMessages.value.findIndex(m => m.id === messageId);
117
+ if (index === -1) {
118
+ throw new Error('消息不存在');
119
+ }
120
+
121
+ const message = scheduledMessages.value[index];
122
+
123
+ // 取消定时器
124
+ if (timers.value[messageId]) {
125
+ clearTimeout(timers.value[messageId]);
126
+ delete timers.value[messageId];
127
+ }
128
+
129
+ // 更新状态
130
+ message.status = 'cancelled';
131
+ saveMessages();
132
+
133
+ // 触发事件
134
+ emit('message-cancelled', message);
135
+ };
136
+
137
+ /**
138
+ * 获取所有待发送消息
139
+ * @returns {Array} 消息列表
140
+ */
141
+ const getMessages = () => {
142
+ return scheduledMessages.value.filter(m => m.status === 'pending');
143
+ };
144
+
145
+ /**
146
+ * 获取单个消息
147
+ * @param {string} messageId - 消息ID
148
+ * @returns {Object} 消息对象
149
+ */
150
+ const getMessage = (messageId) => {
151
+ return scheduledMessages.value.find(m => m.id === messageId);
152
+ };
153
+
154
+ /**
155
+ * 为消息设置定时器
156
+ * @private
157
+ */
158
+ const scheduleMessage = (message) => {
159
+ if (message.status !== 'pending') return;
160
+
161
+ const now = new Date();
162
+ const delay = message.scheduledTime - now;
163
+
164
+ if (delay <= 0) {
165
+ // 时间已过期,立即发送
166
+ sendMessage(message);
167
+ return;
168
+ }
169
+
170
+ // 设置定时器
171
+ const timerId = setTimeout(() => {
172
+ sendMessage(message);
173
+ }, delay);
174
+
175
+ timers.value[message.id] = timerId;
176
+ };
177
+
178
+ /**
179
+ * 发送消息
180
+ * @private
181
+ */
182
+ const sendMessage = (message) => {
183
+ message.status = 'sent';
184
+ message.sentAt = new Date();
185
+ saveMessages();
186
+
187
+ // 清理定时器
188
+ if (timers.value[message.id]) {
189
+ delete timers.value[message.id];
190
+ }
191
+
192
+ // 触发事件
193
+ emit('message-sent', message);
194
+ };
195
+
196
+ /**
197
+ * 保存消息到存储
198
+ * @private
199
+ */
200
+ const saveMessages = () => {
201
+ const toSave = scheduledMessages.value.map(msg => ({
202
+ ...msg,
203
+ scheduledTime: msg.scheduledTime.toISOString()
204
+ }));
205
+ saveToStorage(STORAGE_KEY, toSave);
206
+ };
207
+
208
+ /**
209
+ * 生成消息ID
210
+ * @private
211
+ */
212
+ const generateMessageId = () => {
213
+ return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
214
+ };
215
+
216
+ /**
217
+ * 注册事件监听器
218
+ * @param {string} event - 事件名称
219
+ * @param {Function} callback - 回调函数
220
+ * @returns {Function} 取消监听函数
221
+ */
222
+ const on = (event, callback) => {
223
+ if (!listeners.value[event]) {
224
+ listeners.value[event] = [];
225
+ }
226
+ listeners.value[event].push(callback);
227
+
228
+ // 返回取消监听函数
229
+ return () => {
230
+ listeners.value[event] = listeners.value[event].filter(cb => cb !== callback);
231
+ };
232
+ };
233
+
234
+ /**
235
+ * 触发事件
236
+ * @private
237
+ */
238
+ const emit = (event, data) => {
239
+ if (listeners.value[event]) {
240
+ listeners.value[event].forEach(callback => {
241
+ try {
242
+ callback(data);
243
+ } catch (error) {
244
+ console.error(`Error in event listener for "${event}":`, error);
245
+ }
246
+ });
247
+ }
248
+ };
249
+
250
+ /**
251
+ * 清理所有定时器
252
+ */
253
+ const cleanup = () => {
254
+ Object.values(timers.value).forEach(timerId => {
255
+ clearTimeout(timerId);
256
+ });
257
+ timers.value = {};
258
+ };
259
+
260
+ /**
261
+ * 获取统计信息
262
+ * @returns {Object} 统计信息
263
+ */
264
+ const getStats = () => {
265
+ return {
266
+ total: scheduledMessages.value.length,
267
+ pending: scheduledMessages.value.filter(m => m.status === 'pending').length,
268
+ sent: scheduledMessages.value.filter(m => m.status === 'sent').length,
269
+ cancelled: scheduledMessages.value.filter(m => m.status === 'cancelled').length
270
+ };
271
+ };
272
+
273
+ return {
274
+ scheduledMessages,
275
+ initialize,
276
+ addMessage,
277
+ updateMessage,
278
+ cancelMessage,
279
+ getMessages,
280
+ getMessage,
281
+ on,
282
+ cleanup,
283
+ getStats
284
+ };
285
+ };
286
+
287
+ /**
288
+ * 全局服务实例
289
+ */
290
+ let globalService = null;
291
+
292
+ /**
293
+ * 获取全局服务实例
294
+ */
295
+ export const getScheduledSendService = () => {
296
+ if (!globalService) {
297
+ globalService = createScheduledSendService();
298
+ globalService.initialize();
299
+ }
300
+ return globalService;
301
+ };
302
+
303
+ /**
304
+ * 重置全局服务(用于测试)
305
+ */
306
+ export const resetScheduledSendService = () => {
307
+ if (globalService) {
308
+ globalService.cleanup();
309
+ }
310
+ globalService = null;
311
+ };