9433cfb9创建于 2025年12月31日历史提交
<template>
  <scroll-view class="container">
    <view class="status-section">
      <text class="status-label">Worker状态: </text>
      <text class="status-text">{{statusText}}</text>
    </view>

    <!-- #ifdef APP-IOS -->
    <view class="ios-tip-section">
      <text class="ios-tip-text">⚠️ 提示:Windows系统标准基座iOS平台因平台限制无法运行本地UTS插件,需要自定义基座才能使用示例中的uts-worker插件</text>
    </view>
    <!-- #endif -->

    <view class="button-group">
      <text class="description-text">操作步骤:1.创建Worker 2.发送数据测试(消息监听已在创建Worker时添加)</text>
      <button class="btn" type="primary" :disabled="created_boolean" @click="create">UTS插件中创建Worker</button>
      <button class="btn" @click="destory" :disabled="workerStatus != 'created'">UTS插件中销毁Worker</button>
    </view>

    <view class="input-section">
      <text class="section-title">输入测试值:</text>
      <text class="description-text">点击发送按钮后,会将输入值传给WorkerTask,在子线程执行+1操作后返回结果</text>
      <input class="input-field" v-model="inputValue" type="number" placeholder="请输入数字" />
			<button class="btn" type="primary" @click="sendMessage" :disabled="workerStatus != 'created'">通过UTS插件发送到WorkerTask (值+1)</button>
    </view>

    <view class="log-section">
      <text class="section-title">通信日志:</text>
      <scroll-view class="log-container" scroll-y="true">
        <view v-for="(log, index) in logs" :key="index" class="log-item">
          <text :class="['log-text', log.type]">{{log.message}}</text>
        </view>
      </scroll-view>
      <button @click="clearLogs" class="btn clear-btn">清空日志</button>
    </view>
  </scroll-view>
</template>

<script setup lang="uts">
  import { onWorkerError, createWorkers, sendWorkerMessage, onWorkerMessage, destroyWorker, UTSWorkerAddListenerOptions, UTSWorkerReceiveEventCallback, UTSWorkerSendWorkerMessageOptions, UTSWorkerErrorOptions } from "@/uni_modules/uts-worker";

  const created_boolean = ref(false)
  const workerStatus = ref('none') // none, created, destroyed
  const isListening = ref(false)
  const logs = ref([] as Array<UTSJSONObject>)
  const inputValue = ref('1') // 默认值为1
  const taskResult = ref('')

  const statusText = computed((): string => {
    switch(workerStatus.value) {
      case 'none': return '未创建';
      case 'created': return '已创建';
      case 'destroyed': return '已销毁';
      default: return '未知';
    }
  })

  // 添加日志方法
  function addLog(message: string, type: string = 'info') {
    const now = new Date();
    const timeStr = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
    const logItem = {
      message: `[${timeStr}] ${message}`,
      type: type,
      time: timeStr
    } as UTSJSONObject;
    logs.value.unshift(logItem);
    // 限制日志数量
    if (logs.value.length > 50) {
      logs.value = logs.value.slice(0, 50);
    }
  }

  // 创建Worker
  function create() {
    createWorkers();
    workerStatus.value = 'created';
    addLog('Worker创建成功', 'success');
    created_boolean.value = true;
    // #ifndef APP-IOS
    // 添加消息监听
    onWorkerMessage({
      success: (res : any) => {
        const result = (JSON.parse(JSON.stringify(res)) as UTSJSONObject).getAny('result') as UTSJSONObject;
        const resultData = result.getString('data');
        taskResult.value = resultData as string;
        inputValue.value = taskResult.value
        addLog(`收到WorkerTask返回: ${resultData}`, 'receive');
      }
    });

    // 添加错误监听
    onWorkerError({
      success: (error : any) => {
        const errorMsg = (error as UTSJSONObject).getString('message');
        addLog(`Worker错误: ${errorMsg}`, 'error');
        console.log("Worker错误:", error);
      }
    } as UTSWorkerErrorOptions);
    // #endif
  }

  // 向workerTask发送消息
  function sendMessage() {
    // 检查输入值
    if (inputValue.value == '') {
      addLog('请输入有效的数字', 'warning');
      return;
    }
    // #ifdef APP-IOS
    // 添加消息监听
    onWorkerMessage({
      success: (res : any) => {
        // 临时注释后续需要排查 原生Object转UTSJSONObject无效的问题
        // const result = (res as UTSJSONObject).getAny('result') as UTSJSONObject;
        // const resultData = result.getString('data');

        const result = res["result"];
        const resultData = result["data"];
        taskResult.value = resultData as string;
        inputValue.value = taskResult.value
        addLog(`收到WorkerTask返回: ${resultData}`, 'receive');
      }
    });

    // 添加错误监听
    onWorkerError({
      success: (error : any) => {
        const errorMsg = (error as UTSJSONObject).getString('message');
        addLog(`Worker错误: ${errorMsg}`, 'error');
        console.log("Worker错误:", error);
      }
    } as UTSWorkerErrorOptions);
    // #endif

    const options = {
      data: inputValue.value,
      needReply: true
    } as UTSWorkerSendWorkerMessageOptions;

    sendWorkerMessage(options);
    addLog(`发送值到WorkerTask: ${inputValue.value}`, 'send');
  }

  // 销毁Worker
  function destory() {
    destroyWorker();
    workerStatus.value = 'destroyed';
    isListening.value = false;
    addLog('Worker已销毁', 'warning');
    created_boolean.value = false;
  }

  // 清空日志
  function clearLogs() {
    logs.value = [];
  }

  function test_resetInputValue() {
    inputValue.value = '1'
  }

  function test_taskResult():string {
    return taskResult.value
  }

  onUnload(() => {
    destory();
  })

  defineExpose({
    test_resetInputValue,
    create,
    sendMessage,
    test_taskResult
  })

</script>

<style>
  .container {
    flex: 1;
    padding: 10px;
  }

  .status-section {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20px;
    padding: 10px;
    background-color: #ffffff;
    border-radius: 8px;
  }

  .status-label {
    font-size: 16px;
    color: #666666;
  }

  .status-text {
    font-size: 16px;
    font-weight: bold;
    margin-left: 8px;
  }


  .button-group {
    flex-direction: column;
    margin-bottom: 20px;
  }

  .input-section {
    margin-bottom: 20px;
    padding: 15px;
    background-color: #ffffff;
    border-radius: 8px;
  }

  .input-field {
    /* #ifdef MP-WEIXIN */
    height: 3em;
    /* #endif */
    width: 100%;
    padding: 12px;
    border: 1px solid #dddddd;
    border-radius: 6px;
    font-size: 16px;
    margin: 10px 0;
    background-color: #ffffff;
  }

  .btn {
    margin-bottom: 10px;
    padding: 5px 10px;
    border-radius: 6px;
    font-size: 14px;
    text-align: center;
  }

  .log-section {
    background-color: #ffffff;
    border-radius: 8px;
    padding: 15px;
  }

  .section-title {
    font-size: 18px;
    font-weight: bold;
    color: #333333;
    margin-bottom: 10px;
  }

  .log-container {
    height: 300px;
    border: 1px solid #dddddd;
    border-radius: 4px;
    padding: 10px;
    margin: 10px 0;
    background-color: #fafafa;
  }

  .log-item {
    margin-bottom: 5px;
  }

  .log-text {
    font-size: 12px;
    line-height: 1.4;
  }

  .log-text.info {
    color: #2196F3;
  }

  .log-text.success {
    color: #4CAF50;
  }

  .log-text.warning {
    color: #ff9800;
  }

  .log-text.error {
    color: #f44336;
  }

  .log-text.send {
    color: #9C27B0;
  }

  .log-text.receive {
    color: #009688;
  }

  .clear-btn {
    background-color: #ff9800;
    font-size: 12px;
    padding: 8px 12px;
    color: #ffffff;
    border-radius: 4px;
    text-align: center;
  }

  .description-text {
    font-size: 14px;
    color: #666666;
    line-height: 1.4;
    margin-bottom: 10px;
  }

  .ios-tip-section {
    margin-bottom: 15px;
    padding: 12px;
    background-color: #fff3cd;
    border: 1px solid #ffeaa7;
    border-radius: 8px;
  }

  .ios-tip-text {
    font-size: 14px;
    color: #856404;
    line-height: 1.4;
  }
</style>