app:
  description: ''
  icon: 🤖
  icon_background: '#FFEAD5'
  mode: workflow
  name: json_translate
  use_icon_as_answer_icon: false
kind: app
version: 0.1.3
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      allowed_file_extensions:
      - .JPG
      - .JPEG
      - .PNG
      - .GIF
      - .WEBP
      - .SVG
      allowed_file_types:
      - image
      allowed_file_upload_methods:
      - local_file
      - remote_url
      enabled: false
      fileUploadConfig:
        audio_file_size_limit: 50
        batch_count_limit: 5
        file_size_limit: 15
        image_file_size_limit: 10
        video_file_size_limit: 100
        workflow_file_upload_limit: 10
      image:
        enabled: false
        number_limits: 3
        transfer_methods:
        - local_file
        - remote_url
      number_limits: 3
    opening_statement: ''
    retriever_resource:
      enabled: true
    sensitive_word_avoidance:
      enabled: false
    speech_to_text:
      enabled: false
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
      language: ''
      voice: ''
  graph:
    edges:
    - data:
        isInIteration: false
        sourceType: start
        targetType: code
      id: 1731659178787-source-1731659181729-target
      source: '1731659178787'
      sourceHandle: source
      target: '1731659181729'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        sourceType: code
        targetType: iteration
      id: 1731659181729-source-1731659184426-target
      source: '1731659181729'
      sourceHandle: source
      target: '1731659184426'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: true
        iteration_id: '1731659184426'
        sourceType: iteration-start
        targetType: code
      id: 1731659184426start-source-1731659360096-target
      source: 1731659184426start
      sourceHandle: source
      target: '1731659360096'
      targetHandle: target
      type: custom
      zIndex: 1002
    - data:
        isInIteration: true
        iteration_id: '1731659184426'
        sourceType: code
        targetType: tool
      id: 1731659360096-source-1731659570395-target
      source: '1731659360096'
      sourceHandle: source
      target: '1731659570395'
      targetHandle: target
      type: custom
      zIndex: 1002
    - data:
        isInIteration: true
        iteration_id: '1731659184426'
        sourceType: tool
        targetType: code
      id: 1731659570395-source-1731659778623-target
      source: '1731659570395'
      sourceHandle: source
      target: '1731659778623'
      targetHandle: target
      type: custom
      zIndex: 1002
    - data:
        isInIteration: false
        sourceType: iteration
        targetType: code
      id: 1731659184426-source-1731659874585-target
      source: '1731659184426'
      sourceHandle: source
      target: '1731659874585'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        sourceType: code
        targetType: end
      id: 1731659874585-source-1731659992069-target
      source: '1731659874585'
      sourceHandle: source
      target: '1731659992069'
      targetHandle: target
      type: custom
      zIndex: 0
    nodes:
    - data:
        desc: ''
        selected: false
        title: 开始
        type: start
        variables:
        - label: json_data
          max_length: 10000
          options: []
          required: true
          type: paragraph
          variable: json_data
      height: 90
      id: '1731659178787'
      position:
        x: 30
        y: 295.5
      positionAbsolute:
        x: 30
        y: 295.5
      selected: true
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        code: "import json\nimport re\n\ndef collect_translatable_text(json_data):\n\
          \    translatable_items = []\n    \n    def is_translatable(value):\n  \
          \      # 如果是数字类型，直接返回False\n        if isinstance(value, (int, float)):\n\
          \            return False\n            \n        # 如果不是字符串，也返回False\n  \
          \      if not isinstance(value, str):\n            return False\n      \
          \  \n        text = str(value).strip()\n        if not text:\n         \
          \   return False\n            \n        non_translatable_patterns = [\n\
          \            r'^#[0-9A-Fa-f]{3,8}$',  # 颜色代码\n            r'^[\\d.]+$',\
          \  # 纯数字\n            r'^[0-9a-fA-F-]{36}$',  # UUID\n            r'^https?://',\
          \  # URL\n            r'^[\\d.:]+$',  # IP地址\n            r'^[\\d-]+$',\
          \  # 日期中的数字和横线\n            r'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}$',\
          \  # 邮箱\n        ]\n        \n        for pattern in non_translatable_patterns:\n\
          \            if re.match(pattern, text):\n                return False\n\
          \                \n        # 检查是否包含至少一个中文字符或字母\n        has_translatable_chars\
          \ = bool(re.search(r'[\\u4e00-\\u9fff]|[a-zA-Z]', text))\n        return\
          \ has_translatable_chars\n\n    def traverse(data, path=[]):\n        if\
          \ isinstance(data, dict):\n            for key, value in data.items():\n\
          \                # 将 key 转换为字符串\n                current_path = path + [str(key)]\n\
          \                if isinstance(value, (dict, list)):\n                 \
          \   traverse(value, current_path)\n                elif is_translatable(value):\n\
          \                    translatable_items.append({\n                     \
          \   'path': current_path,\n                        'text': value\n     \
          \               })\n        elif isinstance(data, list):\n            for\
          \ index, item in enumerate(data):\n                # 将索引转换为字符串\n       \
          \         current_path = path + [str(index)]\n                if isinstance(item,\
          \ (dict, list)):\n                    traverse(item, current_path)\n   \
          \             elif is_translatable(item):\n                    translatable_items.append({\n\
          \                        'path': current_path,\n                       \
          \ 'text': item\n                    })\n\n    traverse(json_data)\n    return\
          \ translatable_items\n\n\ndef main(json_data_string):\n    json_data = json.loads(json_data_string)\n\
          \    items_to_translate = collect_translatable_text(json_data)\n    return\
          \ {\"items_to_translate\":items_to_translate}"
        code_language: python3
        desc: ''
        outputs:
          items_to_translate:
            children: null
            type: array[object]
        selected: false
        title: 抽取
        type: code
        variables:
        - value_selector:
          - '1731659178787'
          - json_data
          variable: json_data_string
      height: 54
      id: '1731659181729'
      position:
        x: 334
        y: 295.5
      positionAbsolute:
        x: 334
        y: 295.5
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        desc: ''
        error_handle_mode: terminated
        height: 191
        is_parallel: false
        iterator_selector:
        - '1731659181729'
        - items_to_translate
        output_selector:
        - '1731659778623'
        - result
        output_type: array[object]
        parallel_nums: 10
        selected: false
        start_node_id: 1731659184426start
        title: 迭代
        type: iteration
        width: 1027
      height: 191
      id: '1731659184426'
      position:
        x: 35.14285714285711
        y: 448.3571428571429
      positionAbsolute:
        x: 35.14285714285711
        y: 448.3571428571429
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 1027
      zIndex: 1
    - data:
        desc: ''
        isInIteration: true
        selected: false
        title: ''
        type: iteration-start
      draggable: false
      height: 48
      id: 1731659184426start
      parentId: '1731659184426'
      position:
        x: 24
        y: 68
      positionAbsolute:
        x: 59.14285714285711
        y: 516.3571428571429
      selectable: false
      sourcePosition: right
      targetPosition: left
      type: custom-iteration-start
      width: 44
      zIndex: 1002
    - data:
        code: "\ndef main(item):\n    return {\n        \"path\": item['path'],\n\
          \        \"text\": item['text']\n    }\n"
        code_language: python3
        desc: ''
        isInIteration: true
        iteration_id: '1731659184426'
        outputs:
          path:
            children: null
            type: array[string]
          text:
            children: null
            type: string
        selected: false
        title: 解析
        type: code
        variables:
        - value_selector:
          - '1731659184426'
          - item
          variable: item
      height: 54
      id: '1731659360096'
      parentId: '1731659184426'
      position:
        x: 109
        y: 68
      positionAbsolute:
        x: 144.1428571428571
        y: 516.3571428571429
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
      zIndex: 1002
    - data:
        desc: ''
        isInIteration: true
        iteration_id: '1731659184426'
        provider_id: google_translate
        provider_name: google_translate
        provider_type: builtin
        selected: false
        title: 翻译
        tool_configurations:
          dest: en
        tool_label: 翻译
        tool_name: translate
        tool_parameters:
          content:
            type: mixed
            value: '{{#1731659360096.text#}}'
        type: tool
      height: 90
      id: '1731659570395'
      parentId: '1731659184426'
      position:
        x: 413
        y: 68
      positionAbsolute:
        x: 448.1428571428571
        y: 516.3571428571429
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
      zIndex: 1002
    - data:
        code: "\ndef main(item,translated_text):\n    translated_item = item.copy()\n\
          \    translated_item['translated_text'] = translated_text\n    return {\n\
          \        \"result\": translated_item\n    }\n"
        code_language: python3
        desc: ''
        isInIteration: true
        iteration_id: '1731659184426'
        outputs:
          result:
            children: null
            type: object
        selected: false
        title: 合并
        type: code
        variables:
        - value_selector:
          - '1731659184426'
          - item
          variable: item
        - value_selector:
          - '1731659570395'
          - text
          variable: translated_text
      height: 54
      id: '1731659778623'
      parentId: '1731659184426'
      position:
        x: 717
        y: 67
      positionAbsolute:
        x: 752.1428571428571
        y: 515.3571428571429
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
      zIndex: 1002
    - data:
        code: "import json\n\ndef update_json_with_translations(json_data, translated_items):\n\
          \    \"\"\"\n    使用翻译后的内容更新原始JSON\n    \"\"\"\n    def set_value_at_path(data,\
          \ path):\n        current = data\n        for i, key in enumerate(path[:-1]):\n\
          \            # 判断当前层级是列表还是字典\n            if isinstance(current, list):\n\
          \                # 将字符串索引转换回整数\n                current = current[int(key)]\n\
          \            else:\n                current = current[key]\n        \n \
          \       # 处理最后一个键\n        last_key = path[-1]\n        if isinstance(current,\
          \ list):\n            return current, int(last_key)\n        return current,\
          \ last_key\n\n    result = json.loads(json.dumps(json_data))  # 创建深拷贝\n\
          \    for item in translated_items:\n        obj, final_key = set_value_at_path(result,\
          \ item['path'])\n        obj[final_key] = item['translated_text']\n    return\
          \ result\n\ndef main(json_data_string,translated_items):\n    json_data\
          \ = json.loads(json_data_string)\n    updated_json = update_json_with_translations(json_data,\
          \ translated_items)\n    return {\n        \"result\": json.dumps(updated_json,ensure_ascii=False,indent=2)\n\
          \    }\n"
        code_language: python3
        desc: ''
        outputs:
          result:
            children: null
            type: string
        selected: false
        title: 组装
        type: code
        variables:
        - value_selector:
          - '1731659184426'
          - output
          variable: translated_items
        - value_selector:
          - '1731659178787'
          - json_data
          variable: json_data_string
      height: 54
      id: '1731659874585'
      position:
        x: 1204.9999999999998
        y: 295.5
      positionAbsolute:
        x: 1204.9999999999998
        y: 295.5
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        desc: ''
        outputs:
        - value_selector:
          - '1731659874585'
          - result
          variable: updated_json
        selected: false
        title: 结束
        type: end
      height: 90
      id: '1731659992069'
      position:
        x: 1197.5714285714287
        y: 411.21428571428567
      positionAbsolute:
        x: 1197.5714285714287
        y: 411.21428571428567
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    viewport:
      x: 59.299999999999955
      y: 71.65000000000009
      zoom: 0.7
