workflow-parser.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /**
  2. * 工作流解析:getActionName、calculateSwipeCoordinates、parseOldFormatAction
  3. * parseWorkflow / parseActions / parseNewFormatAction 仍由主机实现(依赖 state、actionRegistry 与 resolver)
  4. */
  5. function getActionName(action) {
  6. const typeNames = {
  7. 'schedule': '定时执行',
  8. 'adb': 'ADB操作',
  9. 'press': '点击图片',
  10. 'input': '输入文本',
  11. 'swipe': '滑动',
  12. 'string-press': '点击文字',
  13. 'scroll': '滚动',
  14. 'locate': '定位',
  15. 'click': '点击',
  16. 'ocr': '文字识别',
  17. 'extract-messages': '提取消息记录',
  18. 'save-messages': '保存消息记录',
  19. 'generate-summary': '生成总结',
  20. 'ocr-chat': 'OCR识别对话',
  21. 'ocr-chat-history': 'OCR提取消息记录',
  22. 'extract-chat-history': '提取消息记录',
  23. 'generate-history-summary': '生成总结',
  24. 'img-bounding-box-location': '图像区域定位',
  25. 'img-center-point-location': '图像中心点定位',
  26. 'img-cropping': '裁剪图片区域',
  27. 'read-last-message': '读取最后一条消息',
  28. 'read-txt': '读取文本文件',
  29. 'read-text': '读取文本文件',
  30. 'save-txt': '保存文本文件',
  31. 'save-text': '保存文本文件',
  32. 'smart-chat-append': '智能合并聊天记录',
  33. 'ai-generate': 'AI生成',
  34. 'if': '条件判断',
  35. 'for': '循环',
  36. 'while': '循环',
  37. 'delay': '延迟',
  38. 'set': '设置变量',
  39. 'random': '生成随机数',
  40. 'echo': '打印信息',
  41. 'log': '打印信息',
  42. }
  43. const typeName = typeNames[action.type] || action.type
  44. const value = action.value || action.target || ''
  45. const displayValue = typeof value === 'string' ? value : JSON.stringify(value)
  46. if (action.type === 'schedule') {
  47. const condition = action.condition || {}
  48. const interval = condition.interval || '0s'
  49. const repeat = condition.repeat !== undefined ? condition.repeat : 1
  50. const repeatText = repeat === -1 ? '无限循环' : `重复${repeat}次`
  51. return `${typeName}: ${interval}, ${repeatText}`
  52. }
  53. if (action.type === 'input') {
  54. return `${typeName}: ${displayValue.length > 20 ? displayValue.substring(0, 20) + '...' : displayValue}`
  55. }
  56. if (action.type === 'string-press' || action.type === 'click') {
  57. return `${typeName}: ${displayValue.length > 20 ? displayValue.substring(0, 20) + '...' : displayValue}`
  58. }
  59. if (action.type === 'if') return `${typeName}: ${action.condition || ''}`
  60. if (action.type === 'for') return `${typeName}: ${action.variable || ''}`
  61. if (action.type === 'set') return `${typeName}: ${action.variable || ''}`
  62. return `${typeName}: ${displayValue}`
  63. }
  64. function calculateSwipeCoordinates(direction, width, height) {
  65. const margin = 0.15
  66. const swipeDistance = 0.7
  67. let x1, y1, x2, y2
  68. switch (direction) {
  69. case 'up-down':
  70. x1 = x2 = Math.round(width / 2)
  71. y1 = Math.round(height * margin)
  72. y2 = Math.round(height * (margin + swipeDistance))
  73. break
  74. case 'down-up':
  75. x1 = x2 = Math.round(width / 2)
  76. y1 = Math.round(height * (margin + swipeDistance))
  77. y2 = Math.round(height * margin)
  78. break
  79. case 'left-right':
  80. y1 = y2 = Math.round(height / 2)
  81. x1 = Math.round(width * margin)
  82. x2 = Math.round(width * (margin + swipeDistance))
  83. break
  84. case 'right-left':
  85. y1 = y2 = Math.round(height / 2)
  86. x1 = Math.round(width * (margin + swipeDistance))
  87. x2 = Math.round(width * margin)
  88. break
  89. default:
  90. throw new Error(`未知的滑动方向: ${direction}`)
  91. }
  92. return { x1, y1, x2, y2 }
  93. }
  94. function parseOldFormatAction(action) {
  95. const times = action.times && action.times > 0 ? parseInt(action.times, 10) : 1
  96. const data = action.data || ''
  97. const delay = action.delay || ''
  98. if (action.press) {
  99. return { type: 'press', value: action.press, times, data, delay }
  100. }
  101. if (action.input !== undefined) {
  102. return { type: 'input', value: action.input, times, data, delay }
  103. }
  104. if (action.swipe) {
  105. const valid = ['up-down', 'down-up', 'left-right', 'right-left']
  106. if (!valid.includes(action.swipe)) return null
  107. return { type: 'swipe', value: action.swipe, times, data, delay }
  108. }
  109. if (action['string-press']) {
  110. return { type: 'string-press', value: action['string-press'], times, data, delay }
  111. }
  112. if (action.scroll) {
  113. const valid = ['up-down', 'down-up', 'left-right', 'right-left']
  114. if (!valid.includes(action.scroll)) return null
  115. return { type: 'scroll', value: action.scroll, times, data, delay }
  116. }
  117. return null
  118. }
  119. module.exports = {
  120. getActionName,
  121. calculateSwipeCoordinates,
  122. parseOldFormatAction,
  123. }