【AI4CODE】4 Trae 锤一个数据搬运工的小应用

【AI4CODE】目录

【AI4CODE】1 Trae CN 锥安装配置与迁移

【AI4CODE】2 Trae 锤一个 To-Do-List

【AI4CODE】3 Trae 锤一个贪吃蛇的小游戏


应用场景就是从一个 REST API GET 到数据后,经过数据转换 POST 到另一个 REST API。用 Trae CN 折腾了 3 天终于搞成功了,记录一下,好脑瓜不如烂笔头。
在这里插入图片描述

1 构建提示词

1.1 构建整个框架提示词

# 0 数据搬运工 提示词
## 1 应用名称:数据搬运工
## 2 开发代号:DataHauler
## 3 功能包括
- 源端API数据定义:可请求方式,定义URL,请求头headers,请求数据负载 payload,还有测试按钮 请求成功获取 json格式定义的数据

- 目标端API数据定义:可请求方式,定义URL,请求头headers,请求数据负载 payload,还有测试按钮

- 数据对照关系定义:目标端API负载的json数据和源端API数据获取Json数据对照关系定义

- 数据搬运按钮:点击执行数据搬运操作,也可以设置时间周期自动执行搬运

## 4 技术栈:  采用 html+css+javascript的技术栈
## 5 托管部署: 可托管部署在csdn的inscode上
## 6 UI要求: 简洁美观

1.2 开始搬运按钮提示词

7 开始搬运按钮的代码逻辑

  1. 执行【源端测试连接】按钮上代码,获取源端API的响应数据后;
  2. 源端响应数据如下: json { "data": { "rows": [ { "DATE_T": "2025-03-27T13:41:43+08:00", "N_AGE": 55, "P_ID": -300, "S_DATE": "2025-03-27", "S_NAME": "5217" }, { "DATE_T": "2024-04-09T00:00:00+08:00", "N_AGE": 17, "P_ID": 1, "S_DATE": "2024-04-08", "S_NAME": "blma" }, { "DATE_T": "2024-04-09T17:01:36+08:00", "N_AGE": 52, "P_ID": 2, "S_DATE": "2024-04-09", "S_NAME": "白龙马" } ] }, "msg": "", "status": 0, "total": 3 }
  3. 按照映射配置定义的json数据结构 ```json { “P_ID2”: “data.rows[1].P_ID”, “S_NAME2”: “data.rows[1].S_NAME”, “N_AGE2”: “data.rows[1].N_AGE” }

4. 以及目标端请求数据负载模版 ```json

{   "P_ID2": 222,   "S_NAME2": "blmA",   "N_AGE2": 56 } ```
逐行构造目标端API的负载数据
5. 执行【目标端测试连接】按钮上代码
6. 重复执行3-5步

1.3 定时搬运提示词

## 9 V7版本修改为可以定时搬运数据
scheduleTransfer()倒计时结束 直接调用 scheduleTransfer()实现定时搬运数据
在【定时搬运】按钮上显示倒计时

1.4 补充说明

  • 首先我的前端三件套(HTML+CSS+JavaScript)是很菜的,很多都是现学现问的。

  • 后端用的 Goland 开发的通用后端 REST2SQL 简单配置一下数据库连接字符串就可以提供 所有数据库表和视图的 REST 服务,甚至是直接执行SQL。
    在这里插入图片描述

  • 前端服务用在 Trae 下安装的 live-server 插件 在这里插入图片描述

  • 整个都是用的 Builder 模式,构建过程不是很顺利,经常翻车,有时候是直接拷贝代码为 Trae 来修改,修改多次都不能满意就亲自上手,用的多了就知道如何用自然语言和 Trae 交互了。

2 数据搬运工的全部代码

2.1 index.html

页面布局

<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>数据搬运工 - DataHauler</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div class="container">
    <h1>数据搬运工</h1>

    <div class="config-container">
      <!-- 源端API配置 -->
      <div class="api-config source-config">
        <h2>源端API配置</h2>
        <form id="sourceApiForm">
          <div class="form-group">
            <label for="sourceUrl">请求方法和API地址:</label>
            <div class="form-group row">
              <select id="sourceMethod" required>
                <option value="GET" selected>GET</option>
                <option value="POST">POST</option>
                <option value="PUT">PUT</option>
                <option value="DELETE">DELETE</option>
              </select>
              <input type="text" id="sourceUrl" placeholder="http://127.0.0.1:5217/rest/dataTable" required>
            </div>
          </div>
          <div class="form-group">
            <label for="sourceHeaders">请求头:</label>
            <textarea id="sourceHeaders" rows="3" placeholder="{}" Authorization\": \"Bearer token\"}"></textarea>
          </div>
          <div class="form-group">
            <label for="sourcePayload">请求负载:</label>
            <textarea id="sourcePayload" rows="3" placeholder="{}" param1\": \"value1\"}"></textarea>
          </div>
          <button type="button" id="testSourceApi">源端测试连接</button>
          <div class="form-group">
            <label for="sourceResponse">响应数据:</label>
            <textarea id="sourceResponse" rows="5" placeholder="源端API响应数据将显示在这里" readonly></textarea>
          </div>
        </form>
      </div>

      <!-- 目标端API配置 -->
      <div class="api-config target-config">
        <h2>目标端API配置</h2>
        <form id="targetApiForm">
          <div class="form-group">
            <label for="targetUrl">请求方法和API地址:</label>
            <div class="form-group row">
              <select id="targetMethod" required>
                <option value="GET">GET</option>
                <option value="POST" selected>POST</option>
                <option value="PUT">PUT</option>
                <option value="DELETE">DELETE</option>
              </select>
              <input type="text" id="targetUrl" placeholder="https://api.example.com/insert" required>
            </div>
          </div>
          <div class="form-group">
            <label for="targetHeaders">请求头:</label>
            <textarea id="targetHeaders" rows="3" placeholder="{}" Content-Type\": \"application/json\"}"></textarea>
          </div>
          <div class="form-group">
            <label for="targetPayload">请求负载模板:</label>
            <textarea id="targetPayload" rows="3" placeholder="{}" data\": \"{{sourceData}}\"}"></textarea>
          </div>
          <button type="button" id="testTargetApi">目标端测试连接</button>
          <div class="form-group">
            <label for="targetResponse">响应数据:</label>
            <textarea id="targetResponse" rows="5" placeholder="目标端API响应数据将显示在这里" readonly></textarea>
          </div>
        </form>
      </div>
    </div>

    <!-- 数据映射配置 -->
    <div id="mappingEditor" class="mapping-config">
      <h2>数据映射关系</h2>
      <div class="form-group">
        <textarea id="mappingContent" rows="10"
          placeholder='[{"P_ID2": "data.rows[0].P_ID","S_NAME2": "data.rows[0].S_NAME","N_AGE2": "data.rows[0].N_AGE"}]'
          class="json-editor"></textarea>
      </div>
    </div>
    <div style="text-align:center; margin: 10px 40px;">
      <button type="button" id="loadFromLocal">本地加载配置</button>
      <button type="button" id="saveAllConfig">保存当前配置</button>
    </div>
  </div>

  <!-- 操作按钮 -->
  <div class="actions">
    <button id="startTransfer">开始搬运</button>
    <button id="scheduleTransfer">定时搬运</button>
  </div>
  </div>

  <script src="app.js"></script>
</body>

</html>

2.2 style.css

CSS样式

/* 基础样式重置 */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Segoe UI', system-ui, sans-serif;
  line-height: 1;
  padding: 5px;
  background-color: #f8f9fa;
  color: #333;
}

h1 {
  text-align: center;
  margin: 0rem 0;
  padding: 1rem 0;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 15px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.config-container h2 {
  text-align: center;
  margin: 1.5rem 0;
  padding: 0.5rem;
  font-size: 1.5rem;
}

/* 三栏布局样式 */
.config-container {
  display: flex;
  gap: 15px;
  margin-bottom: 1rem;
}

.api-config {
  flex: 1;
}

.api-config {
  flex: 1;
  padding: 5px;
  background: white;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  margin-bottom: 5px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.mapping-config {
  margin-top: 1rem;
}

.actions {
  display: flex;
  gap: 1rem;
  justify-content: center;
  margin-top: 2rem;
}

.source-config {
  order: 1;
  flex: 1;
}

.target-config {
  order: 2;
  flex: 1;
}

/* 表单样式 */
.form-group {
  margin-bottom: 0.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}

.form-group.row {
  flex-direction: row;
  align-items: center;
}

.form-group.row select {
  flex: 0.5;
  margin-right: 10px;
}

.form-group.row input {
  flex: 5;
}

.form-group label {
  font-weight: 600;
  color: #555;
}

input,
textarea {
  padding: 0.8rem;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 1rem;
  font-family: Consolas, monospace;
}

textarea {
  min-height: 100px;
  resize: vertical;
}

#sourceResponse,
#targetResponse {
  min-height: 120px;
}

/* 按钮样式 */
button {
  padding: 0.5rem 3rem;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.2s;
  font-weight: 600;
}

#testSourceApi,
#testTargetApi {
  background: #576b95;
  color: white;
}

#testSourceApi:hover,
#testTargetApi:hover {
  opacity: 0.9;
}

/* 数据映射区域 */
.mapping-config {
  margin-bottom: 1rem;
  padding: 1rem;
  border: 1px solid #eee;
  border-radius: 8px;
}

/* 操作按钮区域 */
.actions {
  display: flex;
  gap: 30rem;
  justify-content: center;
}

#startTransfer {
  background: #07c160;
  color: white;
  padding: 10px 80px;
  border-radius: 25px;
  box-shadow: 0 2px 6px rgba(7, 193, 96, 0.3);
}

#testSourceApi {
  display: block;
  margin: 0.5rem auto;
  text-align: center;
}

#testTargetApi {
  display: block;
  margin: 0.5rem auto;
  text-align: center;
}

#scheduleTransfer {
  background: #6467f2;
  color: white;
  padding: 10px 50px;
}

#startTransfer:hover,
#scheduleTransfer:hover {
  opacity: 0.9;
}

2.3 app.js

代码逻辑

// 数据搬运工核心功能
class DataHauler {
  constructor() {
    this.sourceApi = {
      method:'',
      url: '',
      headers: {},
      payload: {}
    };

    this.targetApi = {
      method:'',
      url: '',
      headers: {},
      payloadTemplate: ''
    };

    // 初始化表单默认值
    document.getElementById('sourceHeaders').value = '{}';
    document.getElementById('sourcePayload').value = '{}';
    document.getElementById('targetHeaders').value = '{}';
    document.getElementById('targetPayload').value = '{}';
    document.getElementById('mappingContent').value = '{}';
    this.mappings = {};

    // 初始化事件监听
    this.initEventListeners();
   
    // 添加API配置文件输入元素
    const configFileInput = document.createElement('input');
    configFileInput.type = 'file';
    configFileInput.accept = '.json';
    configFileInput.style.display = 'none';
    configFileInput.addEventListener('change', (e) => this.loadConfigFromFile(e));
    document.body.appendChild(configFileInput);

    // 移除保存API配置按钮
    const saveApiBtn = document.querySelector('.button-group button:first-child');
    if (saveApiBtn && saveApiBtn.textContent === '保存API配置') {
      saveApiBtn.remove();
    }

    // 绑定从本地加载按钮事件
    document.getElementById('loadFromLocal').addEventListener('click', () => {
      const choice = confirm('确定要加载全部配置吗?\n\n确定 - 加载全部配置\n取消 - 不加载');
      if (choice) {
        //apiConfigFileInput.click();
        configFileInput.click();
      }
    });
  }

  // 初始化事件监听
  initEventListeners() {
    // 测试源端API连接
    document.getElementById('testSourceApi').addEventListener('click', () => {
      this.testSourceApi();
    });

    // 测试目标端API连接
    document.getElementById('testTargetApi').addEventListener('click', () => {
      this.testTargetApi();
    });

    // 开始搬运数据
    document.getElementById('startTransfer').addEventListener('click', () => {
      this.startTransfer();
    });

    // 定时搬运数据
    document.getElementById('scheduleTransfer').addEventListener('click', () => {
      this.scheduleTransfer();
    });
  }

  // 测试源端API连接
  async testSourceApi() {
    try {
      // 获取表单数据
      const sourceUrl = document.getElementById('sourceUrl').value.trim();
      if (!sourceUrl) {
        throw new Error('请填写源端API地址');
      }

      this.sourceApi.url = sourceUrl;

      // 解析请求头JSON
      const headersValue = document.getElementById('sourceHeaders').value.trim();
      this.sourceApi.headers = headersValue ? JSON.parse(headersValue) : {};

      // 解析请求负载JSON
      const payloadValue = document.getElementById('sourcePayload').value.trim();
      this.sourceApi.payload = payloadValue ? JSON.parse(payloadValue) : {};

      // 获取请求方法
      this.sourceApi.method = document.getElementById('sourceMethod').value;

      // 调用API
      const requestOptions = {
        method: this.sourceApi.method,
        headers: this.sourceApi.headers
      };

      // 只有非GET请求才需要body
      if (this.sourceApi.method !== 'GET' && Object.keys(this.sourceApi.payload).length > 0) {
        requestOptions.body = JSON.stringify(this.sourceApi.payload);
      }

      const response = await this.callApi(this.sourceApi.url, requestOptions);

      // 检查返回数据是否有效
      if (!response) {
        throw new Error('返回数据不能为空');
      }

      let formattedResponse;

      // 处理不同类型的响应数据
      if (typeof response === 'string') {
        try {
          // 尝试解析为JSON
          const parsed = JSON.parse(response);
          formattedResponse = JSON.stringify(parsed, null, 2);
        } catch (e) {
          // 如果不是JSON,直接显示原始字符串
          formattedResponse = response;
        }
      } else if (typeof response === 'object') {
        // 如果是对象,格式化为JSON字符串
        formattedResponse = JSON.stringify(response, null, 2);
      } else {
        // 其他类型转换为字符串
        formattedResponse = String(response);
      }

      document.getElementById('sourceResponse').value = typeof formattedResponse === 'string' ? formattedResponse.replace(/\\"/g, '"') : JSON.stringify(formattedResponse, null, 2).replace(/\\"/g, '"');
      return response; // 返回数据用于后续处理
    } catch (error) {
      document.getElementById('sourceResponse').value = `错误: ${error.message}`;
      throw error; // 重新抛出错误以便外部捕获
    }
  }

  // 测试目标端API连接
  async testTargetApi() {
    try {
      // 获取表单数据
      this.targetApi.url = document.getElementById('targetUrl').value;
      this.targetApi.headers = JSON.parse(document.getElementById('targetHeaders').value || '{}');
      this.targetApi.payloadTemplate = document.getElementById('targetPayload').value;
      this.targetApi.method = document.getElementById('targetMethod').value;

      // 调用API
      const response = await this.callApi(this.targetApi.url, {
        method: this.targetApi.method,
        headers: this.targetApi.headers,
        body: this.targetApi.payloadTemplate
      });

      // 将响应数据显示在目标端响应框中
      document.getElementById('targetResponse').value = typeof response === 'string' ? response : JSON.stringify(response, null, 2).replace(/\\"/g, '"');
    } catch (error) {
      document.getElementById('targetResponse').value = `错误: ${error.message}`;
    }
  }

  // 开始搬运数据
  async startTransfer() {    
    try {
      // 1. 测试源端API
      const sourceData = await this.testSourceApi();  

      // 2. 遍历源数据行并应用映射
      const parsed = JSON.parse(sourceData);
      
      // 从映射配置中动态获取rows路径
      const firstMapping = Object.values(this.mappings)[0];
      const rowsPathMatch = firstMapping.match(/data\.(rows\[\d+\]|rows)/);
      const rowsPath = rowsPathMatch ? rowsPathMatch[0] : 'data.rows'; // 使用匹配到的路径或默认路径
      // 动态获取rows数组
      const rows = rowsPath.split('.').reduce((obj, key) => {
        // 去除数组索引部分,只保留属性名
        const cleanKey = key.replace(/\[\d+\]/g, '');
        return obj?.[cleanKey];
      }, parsed) || [];
            
      for (const row of rows) {
        // 3. 应用数据映射
        const transformedData = {};
        for (const [targetKey, sourcePath] of Object.entries(this.mappings)) {
          const pathParts = sourcePath.split('.');
          let value = row;
          for (const part of pathParts.slice(2)) { // 跳过data.rows部分
            if (part.includes('[')) {
              const arrayPart = part.replace(/\[\d+\]/g, '');
              value = value[arrayPart];
            } else {
              value = value[part];
            }
          }
          transformedData[targetKey] = value;
        }
        // alert(`成功应用数据映射: ${JSON.stringify(transformedData)}`);
        // 5. 发送到目标端
        this.targetApi.method = document.getElementById('targetMethod').value;
        this.targetApi.url = document.getElementById('targetUrl').value;
        this.targetApi.headers = JSON.parse(document.getElementById('targetHeaders').value || '{}');
        //this.targetApi.payloadTemplate = targetPayload;
        document.getElementById('targetPayload').value = JSON.stringify(transformedData, null, 2);

        const response = await this.callApi(this.targetApi.url, {
          method: this.targetApi.method,
          headers: this.targetApi.headers,
          body: JSON.stringify(transformedData)
        });
        
        console.log(`成功搬运数据行: ${JSON.stringify(row)}`);
      }
      console.log(`${new Date()}数据搬运完成!共处理${rows.length}条记录`);
    } catch (error) {
      alert(`数据搬运失败: ${error.message}`);
    }
  }

  // 定时搬运数据
  scheduleTransfer() {
    // 清除现有的定时器和倒计时
    if (this.timers) {
      clearInterval(this.timers.transfer);
      clearInterval(this.timers.countdown);
    }
    
    const interval = prompt('请输入定时间隔(分钟):', '5217');
    if (interval && !isNaN(interval)) {
      const minutes = parseInt(interval);
      const intervalMs = minutes * 60 * 1000;
      const button = document.getElementById('scheduleTransfer');
      
      // 立即执行一次
      this.startTransfer();
      
      // 设置定时器
      const timerId = setInterval(() => this.startTransfer(), intervalMs);
      
      // 更新按钮文本显示倒计时
      let remaining = minutes * 60;
      const updateButtonText = () => {
        const hours = Math.floor(remaining / 3600);
        const mins = Math.floor((remaining % 3600) / 60);
        const secs = remaining % 60;
        button.textContent = `定时搬运 (${hours}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')})`;
      };
      updateButtonText();
      
      // 每秒更新倒计时
      const countdown = setInterval(() => {
        remaining--;
        updateButtonText();
        
        if (remaining <= 0) {
          remaining = minutes * 60;
        }
      }, 1000);
      
      // 存储定时器ID以便后续清除
      this.timers = {
        transfer: timerId,
        countdown: countdown
      };
    }
  }

 // 加载API配置和映射配置
  async loadConfigFromFile(event) {
    try {
      const file = event.target.files[0];
      if (!file) {
        return;
      }

      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const config = JSON.parse(e.target.result);

          // 设置API配置
          if (config.sourceApi) {
            document.getElementById('sourceMethod').value = config.sourceApi.method;
            document.getElementById('sourceUrl').value = config.sourceApi.url;
            document.getElementById('sourceHeaders').value = JSON.stringify(config.sourceApi.headers, null, 2);
            document.getElementById('sourcePayload').value = JSON.stringify(config.sourceApi.payload, null, 2);
          }

          if (config.targetApi) {
            document.getElementById('targetMethod').value = config.targetApi.method;
            document.getElementById('targetUrl').value = config.targetApi.url;
            document.getElementById('targetHeaders').value = JSON.stringify(config.targetApi.headers, null, 2);
            document.getElementById('targetPayload').value = JSON.stringify(config.targetApi.payloadTemplate, null, 2);
          }

          // 设置映射配置
          if (config.mappings) {
            this.mappings = config.mappings;
            const mappingElement = document.getElementById('mappingContent') || document.getElementById('mappingsTextarea') || document.querySelector('textarea[id^="mapping"]');
            if (mappingElement) {
              mappingElement.value = JSON.stringify(this.mappings, null, 2);
            } else {
              console.warn('未找到映射配置输入框元素');
              // 创建新的映射配置输入框
              const newTextarea = document.createElement('textarea');
              newTextarea.id = 'mappingContent';
              newTextarea.rows = 10;
              newTextarea.cols = 80;
              newTextarea.value = JSON.stringify(this.mappings, null, 2);
              document.body.appendChild(newTextarea);
            }
          }

          alert(`成功从文件 ${file.name} 加载所有配置`);
        } catch (error) {
          alert(`解析配置文件失败: ${error.message}`);
        }
      };

      reader.onerror = () => {
        alert(`读取文件 ${file.name} 时发生错误`);
      };

      reader.readAsText(file);
    } catch (error) {
      alert(`加载配置文件失败: ${error.message}`);
    }
  }

  // 保存全部配置
  async saveAllConfig() {
    try {
      // 验证JSON格式
      const validateJSON = (jsonString) => {
        try {
          JSON.parse(jsonString);
          return true;
        } catch (e) {
          return false;
        }
      };

      // 获取并验证所有表单数据
      const sourceHeaders = document.getElementById('sourceHeaders').value;
      const sourcePayload = document.getElementById('sourcePayload').value;
      const targetHeaders = document.getElementById('targetHeaders').value;
      const targetPayload = document.getElementById('targetPayload').value;
      const mappingContent = document.getElementById('mappingContent').value;

      if (!validateJSON(sourceHeaders) || !validateJSON(sourcePayload) ||
        !validateJSON(targetHeaders) || !validateJSON(targetPayload) ||
        !validateJSON(mappingContent)) {
        throw new Error('请检查JSON格式是否正确');
      }

      // 合并所有配置
      const config = {
        sourceApi: {
          method: document.getElementById('sourceMethod').value,
          url: document.getElementById('sourceUrl').value,
          headers: JSON.parse(sourceHeaders),
          payload: JSON.parse(sourcePayload)
        },
        targetApi: {
          method: document.getElementById('targetMethod').value,
          url: document.getElementById('targetUrl').value,
          headers: JSON.parse(targetHeaders),
          payloadTemplate: JSON.parse(targetPayload)
        },
        mappings: JSON.parse(mappingContent)
      };

      // 保存配置
      const blob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      a.href = url;
      a.download = 'dhconfig.json';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);

      alert('所有配置已保存到本地文件dhconfig.json');
    } catch (error) {
      console.error('保存配置时出错:', error);
      alert(`保存配置时出错: ${error.message}`);
    }
  }

  // 初始化事件监听
  initEventListeners() {
    // 测试源端API连接
    document.getElementById('testSourceApi').addEventListener('click', () => {
      this.testSourceApi();
    });

    // 测试目标端API连接
    document.getElementById('testTargetApi').addEventListener('click', () => {
      this.testTargetApi();
    });

    // 开始搬运数据
    document.getElementById('startTransfer').addEventListener('click', () => {
      this.startTransfer();
    });

    // 定时搬运数据
    document.getElementById('scheduleTransfer').addEventListener('click', () => {
      this.scheduleTransfer();
    });

    // 保存配置
    document.getElementById('saveAllConfig').addEventListener('click', () => {
      this.saveAllConfig();
    });
  }
   
  // 通用API调用方法
  async callApi(url, options) {
    try {
      const response = await fetch(url, options);
      if (!response.ok) {
        throw new Error(`HTTP错误! 状态码: ${response.status}`);
      }

      // 检查响应内容类型是否为JSON
      const contentType = response.headers.get('content-type');
      if (contentType && contentType.includes('application/json')) {
        const data = await response.json();

        // 验证返回数据是否为对象
        if (typeof data !== 'object' || data === null) {
          throw new Error('返回数据必须是JSON对象');
        }

        return data;
      } else {
        // 如果不是JSON格式,返回原始文本
        return await response.text();
      }
    } catch (error) {
      console.error('API调用失败:', error);
      throw error; // 重新抛出错误以便外部捕获
    }
  }
}

// 初始化应用
window.addEventListener('DOMContentLoaded', () => {
  new DataHauler();
});

2.4 dhconfig.json

配置文件

{
  "sourceApi": {
    "method": "GET",
    "url": "http://127.0.0.1:5217/rest/data_type",
    "headers": {},
    "payload": {}
  },
  "targetApi": {
    "method": "POST",
    "url": "http://127.0.0.1:5217/rest/data_type2 ",
    "headers": {},
    "payloadTemplate": {}
  },
  "mappings": {
    "P_ID2": "data.rows[1].P_ID",
    "S_NAME2": "data.rows[1].S_NAME",
    "N_AGE2": "data.rows[1].N_AGE"
  }
}

3 实操演练

3.1 源端 API GET 数据

首先配置源端 API保证能 GET 到数据,配置好API的URL地址,点【源端测试连接】,源端响应数据应该能看到数据才行。比如如下截图:
在这里插入图片描述
数据库表的原始数据如下截图:
在这里插入图片描述

3.2 目标端 API POST 数据

配置目标端 API 地址,请求负载,点【目标端测试连接】,目标端有响应数据显示。比如如下截图:
在这里插入图片描述
数据库验证时候 POST 成功:
在这里插入图片描述

3.3 配置数据映射关系 JSON

  • 源数据
{
  "data": {
    "rows": [
      {
        "DATE_T": "2025-04-01T09:01:40+08:00",
        "N_AGE": 55,
        "P_ID": -300,
        "S_DATE": "2025-04-01",
        "S_NAME": "5217"
      },
      {
        "DATE_T": "2025-04-01T09:01:40+08:00",
        "N_AGE": 17,
        "P_ID": 1,
        "S_DATE": "2025-04-01",
        "S_NAME": "blma"
      },
      {
        "DATE_T": "2025-04-01T09:01:40+08:00",
        "N_AGE": 52,
        "P_ID": 2,
        "S_DATE": "2025-04-01",
        "S_NAME": "白龙马"
      }
    ]
  },
  "msg": "",
  "status": 0,
  "total": 3
}
  • 目标数据负载
{
  "P_ID2": 222,
  "S_NAME2": "blmA",
  "N_AGE2": 56
}
  • 数据映射关系定义
{
  "P_ID2": "data.rows[0].P_ID",
  "S_NAME2": "data.rows[0].S_NAME",
  "N_AGE2": "data.rows[0].N_AGE"
}

源数据有5个字段,只需要3个字段,只映射3字段即可。

3.4 开始搬运

万事俱备,见证奇迹:点【开始搬运】按钮执行数据搬运。
在这里插入图片描述
控制台会有搬运日子输出。检查数据库是否搬运成功:
在这里插入图片描述
OK 搬运成功了。

3.5 定时搬运

设置2分钟定时搬运,倒计时开始,倒计时结束成功搬运。
在这里插入图片描述
定时设置成功会先执行一次搬运。然后按设定时间定时搬运。良辰吉时已到,检查一下数据库记录。

在这里插入图片描述
时间间隔 2:01,

OK!


本文完

### 如何使用 Trae 实现算法 Trae 是一种基于混合模型架构的工具,能够在 Builder 模式下智能调度不同的子模型来完成特定的任务[^2]。通过这种设计,Trae 特别适合用于复杂场景下的代码生成和优化工作。 以下是利用 Trae 来实现一个简单算法的具体方法: #### 使用 Trae 的基本流程 1. **定义目标算法** 首先明确要实现的目标算法逻辑。例如,假设我们希望实现快速排序 (Quick Sort),这是一个经典的分治法排序算法。 2. **调用 Trae API 或界面功能** 利用 Trae 提供的功能模块输入算法描述或者伪代码。如果需要更高的准确性,可以尝试提供更详细的上下文说明或示例数据集。 3. **获取并验证生成代码** Trae 将返回一段初步生成的代码片段。对于本案例中的 Quick Sort 算法,可能得到如下 Python 代码: ```python def quick_sort(arr): if len(arr) <= 1: return arr else: pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) # 测试函数 if __name__ == "__main__": test_array = [3, 6, 8, 10, 1, 2, 1] sorted_array = quick_sort(test_array) print(sorted_array) ``` 此代码实现了标准的递归版本快速排序,并附带了一个简单的测试部分以便于运行调试。 4. **进一步调整与改进** 如果初始生成的结果不完全满足需求,则可以通过修改参数设置重新请求,也可以手动编辑生成的内容以适应具体应用场景的要求。 --- #### 关键特性支持 值得注意的是,在实际操作过程中可能会遇到某些挑战,比如如何平衡开发效率与其他能力之间的关系——这正是研发领域常见的“不可能三角”之一所涉及的问题[^1]。然而借助像 Trae 这样的先进工具,可以在一定程度上缓解这些问题带来的压力。 另外需要注意的是,尽管 Claude3.5 在算法类代码生成方面表现优于 GPT-4o 达到约 12.7%,但这并不意味着它总是完美无误;因此始终建议开发者仔细审查自动生成的所有材料后再投入使用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值