前提条件

开发环境

详见 面板小程序 > 搭建环境

产品名称:AI 口腔镜

需求原型

开发者平台创建面板小程序

面板小程序的开发在 小程序开发者 平台上进行操作,首先请前往 小程序开发者平台 完成平台的注册登录。

详细操作步骤可以参考 创建面板小程序

IDE 基于模板创建项目工程

打开 IDE 创建一个基于 AI 口腔镜模板 的面板小程序项目,需要在 Tuya MiniApp IDE 上操作。

详细操作步骤可以参考 初始化项目工程

完成以上步骤后,一个面板小程序的开发模板初始化完成。以下为工程目录的介绍:

├── src
│  	├── api // 面板所有云端 API 请求聚合文件
│  	├── components // 公共组件
│  	├── constant
│  	│   ├── dpCodes.ts // dpCode 常量
│  	│   ├── index.ts // 存放所有的常量配置
│  	├── devices // 设备模型
│  	├── hooks // hooks
│  	├── i18n // 多语言
│  	├── pages
│   │   ├── home // 首页
│   │   ├── report // 分析报告页面
│  	├── redux // redux
│   ├── res // 图片资源 & svg 相关
│   ├── styles // 全局样式
│   ├── types // 全局类型定义
│   ├── utils // 业务常用工具方法
│   ├── app.config.ts
│   ├── app.less
│   ├── app.tsx
│   ├── composeLayout.tsx // 处理监听子设备添加、解绑、DP 变化等
│   ├── global.config.ts
│   ├── mixins.less // less mixins
│   ├── routes.config.ts // 配置路由
│   ├── variables.less // less variables

AI 模型初始化

功能介绍

模板中提供 AI 模型预下载方法,并同时监听 AI 模型下载进度,确保后续 AI 分析功能正常可用。

相关代码段

const handleOralModelDownProgress = (d: any) => {
  dispatch(updateAiModelProgress(d?.progress || 0));
};

useEffect(() => {
  // 初始化模型
  ty.ai.oralDiseaseInit({
    success: () => {
      console.log(`oralDiseaseInit 成功`);
      showToast({
        title: Strings.getLang("ai_model_download_success"),
        icon: "success",
      });
      dispatch(updateUiState({ aiModel: { init: true, progress: 100 } }));
    },
    fail: () => {
      console.log(`oralDiseaseInit 失败`);
      showToast({
        title: Strings.getLang("ai_model_download_fail"),
        icon: "error",
      });
      dispatch(updateUiState({ aiModel: { init: false, progress: 0 } }));
    },
  });
  // 监听模型下载进度
  ty.ai.onOralModelDownProgress(handleOralModelDownProgress);
  return () => {
    ty.ai.offOralModelDownProgress(handleOralModelDownProgress);
  };
}, []);

手机拍照或从相册选择照片并预览

功能介绍

模板中提供了方法,支持用户通过选取相册内容或拍照获取图像并预览。

相关代码段

  import { chooseImage, previewImage } from "@ray-js/ray";
  const [imageSrc, setImageSrc] = useState<string[]>([]);
  // 选择照片
  const handleChooseImage = () => {
    chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: res => {
        console.log('chooseImage success', res);
        setImageSrc(res.tempFilePaths);
      },
      fail: res => {
        console.log('chooseImage fail', res);
      },
    });
  };

  // 预览照片
  const previewChooseImage = (urls, current) => () => {
    previewImage({
      urls,
      current,
      success: res => {
        console.log('previewImage success', res);
      },
      fail: res => {
        console.log('previewImage fail', res);
      },
    });
  };

功能介绍

通过对照片进行 AI 分析,检测口腔疾病、处理图像显示热区并给出治疗建议。

关键 API 代码段

import { ai, env } from "@ray-js/ray";

  const handleClickAnalysis = () => {
    if (imageSrc.length === 0) return;
    if (!aiModelInit) {
      showToast({
        title: Strings.getLang('ai_model_not_init_tip'),
        icon: 'error',
      });
      return;
    }
    showLoading({ title: Strings.getLang('analysis_loading') });
    const path = imageSrc[0];
    const outputPath = `${env.USER_DATA_PATH}/aiReport/`;
    ty.ai.oralDiseasePredictionRun({
      inputImagePath: path,
      outImagePath: outputPath,
      success: d => {
        console.log('===oralDiseasePredictionRun===', d);
        if (d?.nonOral) {
          DialogInstance.alert({
            message: Strings.getLang('analysis_nonOral'),
            confirmButtonText: Strings.getLang('analysis_nonOral_confirm'),
          }).then(() => {
            // on close
          });
        } else {
          dispatch(updateAiReport(d));
          navigateTo({
            url: '/pages/report/index',
          });
        }
        hideLoading();
      },
      fail: e => {
        console.log('===oralDiseasePredictionRun err===', e);
        showToast({
          title: e && JSON.stringify(e),
          icon: 'error',
        });
        hideLoading();
      },
    });
  };