更新记录

1.0.0(2026-06-27)

  • 新版发布

平台兼容性

uni-app(5.01)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

uni-app x(5.01)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × × ×

yt-widget

uni-app x 日历桌面小组件 UTS 插件。提供 日程(Todo)休息日日期标注(节假日/校庆等)小组件样式 的读写能力,并与 iOS / Android 原生桌面小组件数据同步。

特别提醒

  • 购买本插件前,请先试用,请先试用,请先试用,确认满足需求之后再行购买。虚拟物品一旦购买之后无法退款。
  • 如有使用上的疑问、bug,可以进交流群联系作者;
  • 请在合法范围内使用,若使用本插件做非法开发,本方概不负责;
  • 可扫描右侧二维码安装Android示例demo,体验插件功能
  • 插件需先引入再打自定义基座后使用

平台支持

平台 说明
Android 支持。原生能力以 AAR 模式 集成(libs/lib-release.aar),可在 uni-app x 中试用与云打包
iOS 不支持试用普通授权也无法直接使用(见下方「购买与试用说明」)。购买源码后需自行用 Xcode + 苹果开发者账号打包 .appex
HarmonyOS 仅占位,未实现

最低版本要求:

  • iOS:14.0(utssdk/app-ios/config.json
  • Android:API 26 / Android 8.0(utssdk/app-android/config.json

购买与试用说明(请务必阅读)

Android:AAR 模式

由于 Android 打包存在 Compose / Glance 等依赖冲突,本插件对外发布时 统一采用 AAR 模式 集成,不提供可直接修改的 Android 原生工程源码。

  • 插件包内已包含编译好的 utssdk/app-android/libs/lib-release.aar
  • 可直接在 uni-app x 项目中 制作自定义调试基座云打包 进行试用与集成
  • 若需要修改 Android 小组件原生逻辑,请 购买源码授权,并向作者索取 Android 原生源码 后再自行编译 AAR 或集成
  • Android如果需要点击桌面组件启动App并跳转到指定页面需要manifest.json文件中配置UrlSchemes为”swifttest“源码如下:
    "distribute" : {
    /* android打包配置 */
    "android" : {
        ...
        "schemes" : "swifttest"
    },
    ...
    }

iOS:不支持试用,普通授权也无法使用

iOS 桌面小组件(Widget Extension)与主 App 属于 两个独立 Target,且涉及 App Group、证书、描述文件、Bundle ID 等开发者账号专属配置,无法像 Android 一样通过通用 AAR / 预编译包直接试用。

因此:

  1. iOS 不支持试用 — 无法在 DCloud 标准基座或云打包中直接验证 iOS 小组件
  2. 购买普通授权也无法使用 iOS 小组件 — 原因同上,必须持有并配置您自己的苹果开发者账号
  3. iOS 桌面小组件交互说明支持点击跳转到 App(如点击日历日期打开主 App);不支持其他在桌面小组件内的操作(如在组件内切换月份、直接在组件上完成 / 修改日程等,受系统限制)
  4. 购买源码授权后,需向作者索取 iOS 原生源码(含 Widget Extension 工程),再使用 Xcode 登录您自己的苹果开发者账号 打包 .appex 产物

iOS 集成前请提前准备好:

配置项 说明
苹果开发者账号 用于签名主 App 与 Widget Extension
证书(Certificates) 开发 / 发布证书需与 Team 一致
描述文件(Provisioning Profile) 主 App 与 Extension 各需匹配 Bundle ID 的描述文件
App Group 主 App 与 Widget Extension 必须使用同一 App Group,否则无法共享日程 / 标注等数据
Bundle Identifier 主 App、Extension 的 Bundle ID 需与描述文件一致

完成上述配置后,将打包产物集成到 uni-app x 工程,再制作 自定义调试基座云打包 验证。

再次强调:仅购买普通授权、未购买源码并完成 iOS 自行打包的,无法使用 iOS 桌面小组件功能。

引入方式

import * as WidgetManager from '@/uni_modules/yt-widget'

请导入到插件根目录 @/uni_modules/yt-widget,不要深入到 utssdk 子目录。

集成说明

通用

  1. uni_modules/yt-widget 放入项目的 uni_modules 目录。
  2. 修改原生配置(包名、App Group、证书等)后,需 重新制作自定义调试基座云打包 后才能在真机验证小组件。
  3. 验证小组件前建议:卸载旧 App → 安装新包 → 删除桌面旧小组件 → 重新添加

小组件点击跳转到指定页面

桌面小组件点击日期会通过 URL Scheme 唤起主 App,并携带 dayKey 参数(格式 yyyy-MM-dd)。Deep Link 示例:

swifttest://widget/widget-push?dayKey=2026-05-15

swifttest 为插件内置 Scheme 名称,须与 manifest / Info.plist 中配置 保持一致

前置条件:

  1. Android:在 manifest.json 中配置 URL Scheme("schemes": "swifttest"),并调用 clickCalendarOpenApp(true) 或通过 setWidgetStyle({ dayClickOpensApp: true, ... }) 开启点击响应(见 API 说明)。
  2. iOS:插件已在 utssdk/app-ios/Info.plist 注册 swifttest Scheme;主 App 打包产物中也须包含相同 Scheme。
  3. App.vue 中解析 Scheme 并 navigateTo 到目标页面;目标页在 onLoad 中读取 option.dayKey 处理业务逻辑。

uni-app 项目

uni-app(Vue)工程通过 plus.runtime.arguments 获取小组件传入的 Scheme,在 onLaunch / onShow 中解析并跳转。参考 Demo 工程 App.vue

<script>
export default {
  data() {
    return {
      // 避免 onLaunch + onShow 重复处理同一条 Scheme
      lastHandledScheme: ''
    }
  },
  onLaunch: function() {
    var args = plus.runtime.arguments
    this.handleWidgetScheme(args)
  },
  onShow: function() {
    var args = plus.runtime.arguments
    this.handleWidgetScheme(args)
  },
  methods: {
    handleWidgetScheme(scheme) {
      if (scheme == null || scheme.length == 0) {
        return
      }
      if (scheme == this.lastHandledScheme) {
        return
      }
      // 与 Extension / Info.plist 里注册的 scheme 一致
      if (!scheme.startsWith('swifttest://widget/')) {
        return
      }
      this.lastHandledScheme = scheme

      const targetPath = '/widget-push'
      if (!scheme.includes(targetPath)) {
        console.log('[WidgetScheme] 未知 path:', scheme)
        return
      }
      // 解析 dayKey
      let dayKey = ''
      const qIndex = scheme.indexOf('?')
      if (qIndex >= 0) {
        const query = scheme.substring(qIndex + 1)
        const pairs = query.split('&')
        for (let i = 0; i < pairs.length; i++) {
          const pair = pairs[i]
          const eqIndex = pair.indexOf('=')
          if (eqIndex > 0 && pair.substring(0, eqIndex) == 'dayKey') {
            dayKey = pair.substring(eqIndex + 1)
            break
          }
        }
      }
      // 改成你 pages.json 里真实页面路径
      let pageUrl = '/pages/index/index'
      if (dayKey.length > 0) {
        pageUrl = pageUrl + '?dayKey=' + dayKey
      }

      console.log('[WidgetScheme] navigateTo:', pageUrl)

      // 冷启动会先打开首页,稍延迟再跳转更稳
      setTimeout(() => {
        this.lastHandledScheme = ''
        uni.navigateTo({
          url: pageUrl,
          fail: (err) => {
            console.log('[WidgetScheme] navigateTo fail', err)
            // 若已在目标页栈顶,可改用 redirectTo
            // uni.redirectTo({ url: pageUrl })
          }
        })
      }, 300)
    }
  }
}
</script>

说明:

要点 说明
获取 Scheme uni-app 使用 plus.runtime.arguments,在 onLaunchonShow 中均需调用
pageUrl 修改为上表代码中 let pageUrl = '/pages/index/index',换成你 pages.json 中的目标路径
dayKey 小组件点击的日期,可通过 URL 参数传到目标页
防重复 lastHandledScheme 避免冷启动时 onLaunch + onShow 重复跳转
目标页接收 在目标页 onLoad(option) 中读取 option.dayKey 做后续处理

目标页接收 dayKey 示例:

onLoad(option) {
  const dayKey = option.dayKey
  if (dayKey) {
    console.log('来自桌面小组件,点击日期:', dayKey)
  }
}

uni-app x 项目

<script setup lang="uts">
    // #ifdef APP-ANDROID || APP-HARMONY
    let firstBackTime = 0
    // #endif

    // 避免 onLaunch + onAppShow 重复处理同一条 Scheme
    let lastHandledScheme = ''

    /**
     * 解析小组件 Deep Link,例如:
     * swifttest://widget/widget-push?dayKey=2026-05-15
     */
    function handleWidgetScheme(scheme : string | null) {
        if (scheme == null || scheme.length == 0) {
            return
        }
        if (scheme == lastHandledScheme) {
            return
        }
        // 与 Extension / Info.plist 里注册的 scheme 一致
        if (!scheme.startsWith('swifttest://widget/')) {
            return
        }
        lastHandledScheme = scheme

        // path 与 WidgetTest 里 WidgetDeepLink.huaweiMultiScanPath 一致
        const targetPath = '/widget-push'
        if (!scheme.includes(targetPath)) {
            console.log('[WidgetScheme] 未知 path:', scheme)
            return
        }
        // 解析 dayKey
        let dayKey = ''
        const qIndex = scheme.indexOf('?')
        if (qIndex >= 0) {
            const query = scheme.substring(qIndex + 1)
            const pairs = query.split('&')
            for (let i = 0; i < pairs.length; i++) {
                const pair = pairs[i]
                const eqIndex = pair.indexOf('=')
                if (eqIndex > 0 && pair.substring(0, eqIndex) == 'dayKey') {
                    dayKey = pair.substring(eqIndex + 1)
                    break
                }
            }
        }
        // TODO: 改成你 pages.json 里真实页面路径
        let pageUrl = '/pages/index/wigetTarget'
        if (dayKey.length > 0) {
            pageUrl = pageUrl + '?dayKey=' + dayKey
        }

        console.log('[WidgetScheme] navigateTo:', pageUrl)

        // 冷启动会先打开首页,稍延迟再跳转更稳
        setTimeout(() => {
            lastHandledScheme = "";
            uni.navigateTo({
                url: pageUrl,
                fail: (err) => {
                    console.log('[WidgetScheme] navigateTo fail', err)
                    // 若已在目标页栈顶,可改用 redirectTo
                    // uni.redirectTo({ url: pageUrl })
                }
            })
        }, 300)
    }

    onLaunch((options) => {
        console.log('App Launch', options.appScheme)
        // #ifdef APP-IOS || APP-ANDROID
        handleWidgetScheme(options.appScheme)
        // #endif
    })

    onAppShow((options) => {
        console.log('App Show', options.appScheme)
        // #ifdef APP-IOS || APP-ANDROID
        handleWidgetScheme(options.appScheme)
        // #endif
    })

    onAppHide(() => {
        console.log('App Hide')
    })

    // #ifdef APP-ANDROID || APP-HARMONY
    onLastPageBackPress(() => {
        console.log('App LastPageBackPress')
        if (firstBackTime == 0) {
            uni.showToast({
                title: '再按一次退出应用',
                position: 'bottom',
            })
            firstBackTime = Date.now()
            setTimeout(() => {
                firstBackTime = 0
            }, 2000)
        } else if (Date.now() - firstBackTime < 2000) {
            firstBackTime = Date.now()
            uni.exit()
        }
    })

    onExit(() => {
        console.log('App Exit')
    })
    // #endif
</script>

Android

  • 原生实现封装在 utssdk/app-android/libs/lib-release.aarAAR 模式,见上文说明)。
  • 插件依赖 Glance 1.1.1 与 Compose 相关库,见 utssdk/app-android/config.json
  • SCHEDULE_EXACT_ALARMRECEIVE_BOOT_COMPLETED 等权限(由 AAR / Manifest 合并)。
  • 必须使用自定义调试基座或云打包,标准基座无法加载 AAR 与小组件 Receiver。
  • 更新 AAR 或 config.json 后需重新打基座;仅热更新 wgt 无法更新原生小组件能力。
  • 需要修改 Android 原生代码时,请购买源码并向作者索取 Android 工程源码。

iOS

  • 小组件扩展位于 utssdk/app-ios/Plugins/CalendarWidgetExtension.appex(预置产物仅作参考,无法直接用于您的 Bundle ID / 证书)。
  • 必须使用您自己的苹果开发者账号,在 Xcode 中为 Extension 重新签名并打包 .appex
  • 云打包 / 自定义基座时需使用与 Widget Extension 匹配的 描述文件(.mobileprovision)Bundle Identifier
  • deploymentTarget 为 14。
  • 支持点击跳转到 App(如点击日历日期打开主 App);不支持其他桌面小组件内操作(如在组件内切换、直接在组件上改数据等);样式相关 UTS API 在 iOS 侧当前返回「未实现」。
  • 完整 iOS 能力需 购买源码授权 并向作者索取 iOS 原生工程后再自行集成。

iOS nativeResources 配置

iOS 桌面小组件依赖 Widget Extension 与主 App 共享 App Group 数据。uni-app / uni-app x 工程需在项目根目录创建 nativeResources/ios/,配置 Extension 签名与主 App 能力,否则云端打包 / 自定义基座 不会包含 插件内的 .appex 扩展。

目录结构示例:

项目根目录/
├── manifest.json
└── nativeResources/
    └── ios/
        ├── ios-extension.json          # Widget Extension 签名与 entitlements 配置(必填)
        ├── UniApp.entitlements         # 主 App 的 App Group 等 Capabilities(必填)
        └── ios-widget-dev.mobileprovision  # Extension 描述文件(文件名须以 ios 开头)

参考:iOS 原生应用配置文件和资源 · UTS 插件 iOS Extension 说明


1. ios-extension.json(Widget Extension 配置,必填)

用于告诉打包系统如何签名并合并 CalendarWidgetExtension.appex。文件 必须是纯 JSON,不能包含任何注释///* */ 均会导致配置失效)。

示例(请按您的苹果开发者账号 全部替换 为真实值):

{
  "CalendarWidgetExtension.appex": {
    "identifier": "io.dcloud.LYScanUniPlugin.widget",
    "profile": "ios-widget-dev.mobileprovision",
    "plists": {},
    "entitlements": {
      "com.apple.security.application-groups": [
        "group.io.dcloud.LYScanUniPlugin.widget"
      ]
    }
  }
}
字段 说明
CalendarWidgetExtension.appex Extension 文件名,须与插件 utssdk/app-ios/Plugins/.appex 名称 完全一致
identifier Extension 的 Bundle ID,须嵌套在主 App Bundle ID 下(如主 App 为 com.company.app,Extension 可为 com.company.app.widget
profile Extension 专用 描述文件路径,相对于 nativeResources/ios/文件名必须以 ios 开头,否则可能不会参与云端打包
plists 可选,合并到 Extension Info.plist 的 JSON 数据
entitlements 可选,覆盖 Extension entitlements必须配置与主 App 相同的 App Group

2. UniApp.entitlements(主 App 配置,必填)

主 App 须启用与 Extension 相同的 App Group,否则双方无法读写共享的日程 / 标注数据。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.application-groups</key>
    <array>
        <string>group.io.dcloud.LYScanUniPlugin.widget</string>
    </array>
</dict>
</plist>

UniApp.entitlements 中的 App Group 字符串须与 ios-extension.jsonentitlements 中配置的 完全一致


3. Extension 描述文件(.mobileprovision

  1. Apple Developer 创建 App Group(如 group.com.yourcompany.yourapp.widget)。
  2. 为主 App、Widget Extension 分别创建 App ID,并 勾选同一 App Group
  3. 为 Extension 的 App ID 创建 Development / Distribution 描述文件,下载后放到 nativeResources/ios/
  4. 文件名建议以 ios 开头(如 ios-widget-dev.mobileprovision),并在 ios-extension.jsonprofile 字段引用。

4. URL Scheme(小组件点击唤起 App,可选)

插件在 utssdk/app-ios/Info.plist 中注册了 swifttest Scheme。若主 App 打包后点击小组件无法唤起,可在 nativeResources/ios/ 下新增 Info.plist,为主 App 合并相同 Scheme:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLName</key>
            <string>io.dcloud.LYScanUniPlugin</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>swifttest</string>
            </array>
        </dict>
    </array>
</dict>
</plist>

App 侧解析 Scheme 跳转逻辑见上文「小组件点击跳转到指定页面」。


5. 配置检查清单

检查项 要求
App Group 主 App(UniApp.entitlements)与 Extension(ios-extension.jsonID 完全一致
Bundle ID Extension identifier 与描述文件中的 App ID 一致
.appex 名称 ios-extension.json 节点名与插件内文件名 一致
描述文件 放在 nativeResources/ios/profile 路径正确,文件名 ios 开头
JSON 格式 ios-extension.json 禁止注释
重新打包 修改 nativeResources 后须 重新制作自定义基座云打包

购买源码后若自行用 Xcode 重签 Extension,仍须保证上述 App Group、Bundle ID、Scheme 与工程配置一致。

类型定义

类型声明见 utssdk/interface.uts,页面中可通过 WidgetManager.xxx 引用。

TodoInfo

日程条目。

字段 类型 说明
dayKey string 日期,格式 yyyy-MM-dd
title string 日程标题
completed boolean 是否已完成

常用参数类型

类型 说明
AddTodayTodoPara 添加今日日程:titleaddHandler
AddOtherTodoPara 添加指定日期日程:dateStrtitleaddHandler
RemoveTodoPara 删除日程:dateStrtitle 可选,不传则删除该日全部日程
SetTodoCompletedPara 设置完成状态:todoInforesultHandler
SetRestDayPara 单日休息日:dateStrrestDaysetRestDayHandler
SetRestDaysBatchPara 批量休息日:dateStrsrestDaysetRestDayHandler
DayLabelPara 单日标注:dateStrtitle 可选(设置时必传)
SetDayLablesPara 多日期相同标注:datestitleresultHandler
SetDayLablesByDatePara 多日期不同标注:labelsresultHandler
DayLablesInfo 批量标注项:dateKeylables
ClearDayLabelsPara 清除多日期标注:labelsByDatesresultHandler
SetWidgetStylePara 小组件样式:restDayBadgeBgdayLabelTextColortodaySolarCircleBgeventBarIncompleteeventBarCompleteddayClickOpensAppresultHandler

SetWidgetStylePara 字段说明

字段 类型 说明
restDayBadgeBg string? 休息日角标背景色,格式 #RRGGBB#AARRGGBB
dayLabelTextColor string? 节假日 / 标注文字颜色
todaySolarCircleBg string? 今日公历圆圈背景色
eventBarIncomplete string? 未完成日程条颜色
eventBarCompleted string? 已完成日程条颜色
dayClickOpensApp boolean? 点击日历日期是否打开 App(UTS API 仅 Android 可配置;iOS 小组件本身支持点击跳转 App,但不通过此 API 控制)
resultHandler function 操作结果回调

颜色参数规则:

  • 不传某项:保持当前已保存的值不变
  • 传空字符串 "":恢复该项为默认颜色
  • 传具体色值:更新为指定颜色

API 说明

以下 API 均已导出。写操作完成后会触发原生层刷新桌面小组件(具体刷新时机受系统调度影响)。

平台差异setWidgetStyle / clickCalendarOpenApp / resetWidgetStyle 目前 仅 Android 实现;iOS 调用返回「iOS 未实现」。iOS 桌面小组件 支持点击跳转到 App不支持其他组件内操作(如切换、直接在组件上改数据)。

日程

addTodoForToday(para: AddTodayTodoPara)

今天 添加一条日程。

WidgetManager.addTodoForToday({
  title: '晨会',
  addHandler: (result) => {
    console.log(result) // 操作结果描述
  }
})

addTodo(para: AddOtherTodoPara)

指定日期 添加日程。dateStr 格式:yyyy-MM-dd

WidgetManager.addTodo({
  dateStr: '2026-06-01',
  title: '项目评审',
  addHandler: (result) => {
    console.log(result)
  }
})

getAllTodos(): string

获取全部日程。

返回值是 JSON 字符串,不是 Array<TodoInfo>。原因是 UTS 插件向 .uvue 页面返回自定义对象数组时,跨层序列化可能丢失字段;使用 JSON 字符串可稳定传递。

const json = WidgetManager.getAllTodos()
const list = JSON.parseArray<WidgetManager.TodoInfo>(json) ?? []
console.log(list)

解析后每项结构:

{
  "dayKey": "2026-05-30",
  "title": "吃饭",
  "completed": false
}

setTodoCompleted(para: SetTodoCompletedPara)

设置 指定日期 + 指定标题 的第一条匹配日程的完成状态。

WidgetManager.setTodoCompleted({
  todoInfo: {
    dayKey: '2026-05-30',
    title: '吃饭',
    completed: true
  },
  resultHandler: (result) => {
    console.log(result)
  }
})

removeTodo(para: RemoveTodoPara)

删除日程。

  • 传入 title:删除该日下 同名 日程
  • 不传 title 或传空:删除该日 全部 日程
WidgetManager.removeTodo({
  dateStr: '2026-05-30',
  title: '吃饭',
  resultHandler: (result) => {
    console.log(result)
  }
})

clearAllTodos()

清空 所有 日程。

WidgetManager.clearAllTodos()

休息日

setRestDayForDate(para: SetRestDayPara)

设置或取消 单日 休息日。restDay: true 设为休息日,false 取消。

WidgetManager.setRestDayForDate({
  dateStr: '2026-06-07',
  restDay: true,
  setRestDayHandler: (result) => {
    console.log(result)
  }
})

setRestDaysBatch(para: SetRestDaysBatchPara)

批量设置 / 取消休息日。

WidgetManager.setRestDaysBatch({
  dateStrs: ['2026-06-07', '2026-06-08'],
  restDay: true,
  setRestDayHandler: (result) => {
    console.log(result)
  }
})

loadRestDays(): Array\<string>

获取全部休息日日期列表,元素格式 yyyy-MM-dd

const days = WidgetManager.loadRestDays()
console.log(days)

clearAllRestDays(): string

清除全部休息日配置,返回操作结果描述。

const result = WidgetManager.clearAllRestDays()
console.log(result)

日期标注(节假日 / 校庆等)

setDayLabelForDate(para: DayLabelPara)

为指定日期设置标注文字,例如「校庆」「端午调休」。

WidgetManager.setDayLabelForDate({
  dateStr: '2026-06-01',
  title: '校庆',
  resultHandler: (result) => {
    console.log(result)
  }
})

clearDayLabel(para: DayLabelPara)

清除指定日期的标注(只需传 dateStr)。

WidgetManager.clearDayLabel({
  dateStr: '2026-06-01',
  resultHandler: (result) => {
    console.log(result)
  }
})

setDayLabelsBatch(para: SetDayLablesPara)

为多个日期设置 相同 标注。

WidgetManager.setDayLabelsBatch({
  dates: ['2026-06-07', '2026-06-08'],
  title: '放假',
  resultHandler: (result) => {
    console.log(result)
  }
})

setDayLabelsByDate(para: SetDayLablesByDatePara)

为多个日期设置 不同 标注。

WidgetManager.setDayLabelsByDate({
  labels: [
    { dateKey: '2026-06-21', lables: '校庆' },
    { dateKey: '2026-06-22', lables: '端午' }
  ] as WidgetManager.DayLablesInfo[],
  resultHandler: (result) => {
    console.log(result)
  }
})

clearDayLabels(para: ClearDayLabelsPara)

清除多个日期下的标注;无效日期会被跳过。

WidgetManager.clearDayLabels({
  labelsByDates: ['2026-06-07', '2026-06-08'],
  resultHandler: (result) => {
    console.log(result)
  }
})

allDayLabels(): Map\<string, string>

获取全部日期标注。Key 为 yyyy-MM-dd,Value 为标注文字。

const labels = WidgetManager.allDayLabels()

uniAllDayLabels(): string

获取全部日期标注,返回 JSON 字符串(推荐在 uni-app x 页面中使用,避免 Map 跨层序列化问题)。

const json = WidgetManager.uniAllDayLabels()
const data = JSON.parse(json) as UTSJSONObject
Object.keys(data).forEach((key) => {
  console.log(key, data[key])
})

返回示例:

{
  "2026-06-07": "放假",
  "2026-06-08": "校庆"
}

clearAllDayLabels(): string

清除 全部 用户设置的日期标注,并刷新小组件。

const result = WidgetManager.clearAllDayLabels()
console.log(result)

小组件样式(Android)

以下 API 目前 仅 Android 有效;iOS 调用返回「iOS 未实现」。

setWidgetStyle(para: SetWidgetStylePara)

设置小组件样式(颜色、点击行为等)。可同时传入多个字段,未传字段保持原值。

WidgetManager.setWidgetStyle({
  restDayBadgeBg: '#80FF5722',//休息日「休」圆标背景
  dayLabelTextColor: '#FF2196F3',//用户日期标注 **文字色**([setDayLabel] 如「校庆」)
  todaySolarCircleBg: '#FF4CAF50',//大号月历 **当天** 阳历数字圆形背景
  eventBarIncomplete: '#FFFF9800',//未完成日程条背景
  eventBarCompleted: '#FF9E9E9E',//已完成日程条背景 
  dayClickOpensApp: true,//点击行为 false`(默认):点击月历 **日期格** → 弹框显示该日日程 `true`:点击日期格 → 通过 Deep Link 打开宿主 App
  resultHandler: (result) => {
    console.log(result)
  }
})

恢复单项为默认颜色示例(传空字符串):

WidgetManager.setWidgetStyle({
  restDayBadgeBg: '',
  resultHandler: (result) => console.log(result)
})

clickCalendarOpenApp(open: boolean): string

单独设置 点击日历日期是否打开 App仅 Android 可通过此 API 配置;iOS 小组件本身支持点击跳转 App)。

const result = WidgetManager.clickCalendarOpenApp(true)
console.log(result)

resetWidgetStyle(): string

恢复小组件 全部样式为默认值,并将「点击日期打开 App」设为 false

const result = WidgetManager.resetWidgetStyle()
console.log(result)

完整示例(片段)

import * as WidgetManager from '@/uni_modules/yt-widget'

// 添加今日日程
WidgetManager.addTodoForToday({
  title: '吃饭',
  addHandler: (msg) => console.log(msg)
})

// 获取并展示全部日程
const json = WidgetManager.getAllTodos()
const todos = JSON.parseArray<WidgetManager.TodoInfo>(json) ?? []

// 获取全部节假日标注(推荐 JSON 方式)
const labelsJson = WidgetManager.uniAllDayLabels()
const labels = JSON.parse(labelsJson)

// 设为休息日
WidgetManager.setRestDayForDate({
  dateStr: '2026-06-07',
  restDay: true,
  setRestDayHandler: (msg) => console.log(msg)
})

// 设置小组件样式(Android)
WidgetManager.setWidgetStyle({
  todaySolarCircleBg: '#FF4CAF50',
  dayClickOpensApp: false,
  resultHandler: (msg) => console.log(msg)
})

项目内可参考 Demo 工程中的 pages/todos/todos.vuepages/widgetStyle/widgetStyle.vue 等页面。

注意事项

  1. getAllTodos / uniAllDayLabels 返回 JSON 字符串
    页面侧请使用 JSON.parse / JSON.parseArray 解析,不要直接把返回值当作对象或数组使用。

  2. 日期格式
    所有日期参数统一为 yyyy-MM-dd,例如 2026-06-01

  3. 回调说明
    多数写操作通过 addHandler / resultHandler / setRestDayHandler 返回字符串结果,可用于 Toast 或日志提示。

  4. 小组件刷新
    数据写入后会触发原生层刷新;系统可能延迟更新桌面小组件,属正常现象。

  5. Android AAR 模式与更新
    插件以 AAR 形式发布;若自行替换 utssdk/app-android/libs/lib-release.aar,请使用 Kotlin 1.9.x 编译(勿用 Kotlin 2.0 编译 Glance 小组件,否则可能与 uni-app x 基座 Compose 版本冲突导致小组件显示「无法显示内容」)。替换后需重新制作自定义基座。

  6. Android 自定义基座包名
    自定义调试基座的包名须与工程 manifest.json 中 Android 包名一致,否则可能出现 SecurityException: Package xxx does not belong to uid 等权限错误。

  7. iOS 证书、扩展与授权
    Widget Extension 需与主 App 使用匹配的 Team、App Group 与描述文件;不支持试用,普通授权也无法直接使用,必须购买源码后自行用 Xcode + 开发者账号打包 .appex

  8. iOS 小组件交互说明
    iOS 桌面小组件 支持点击跳转到 App不支持其他组件内操作(如在组件内切换、直接在组件上完成 / 修改日程等)。setWidgetStyle / clickCalendarOpenApp / resetWidgetStyle 等样式 UTS API 在 iOS 侧未实现。

  9. iOS nativeResources 配置
    须在项目 nativeResources/ios/ 下配置 ios-extension.jsonUniApp.entitlements 及 Extension 描述文件;详见「iOS nativeResources 配置」。ios-extension.json 必须是 纯 JSON,禁止注释。

  10. 小组件点击跳转
    须在 App.vue 中解析 Scheme 并跳转目标页,详见「小组件点击跳转到指定页面」;Android 另需配置 URL Scheme 并开启 clickCalendarOpenApp

目录结构

yt-widget/
├── utssdk/
│   ├── interface.uts          # 对外类型定义
│   ├── app-ios/
│   │   ├── index.uts          # iOS UTS 实现
│   │   ├── WidgetBridge.swift # iOS 原生桥接
│   │   └── Plugins/           # Widget Extension(.appex,需自行重签)
│   ├── app-android/
│   │   ├── index.uts          # Android UTS 实现
│   │   ├── config.json        # Android 依赖配置
│   │   └── libs/              # Android AAR(lib-release.aar)
│   └── app-harmony/           # 鸿蒙占位
├── package.json
└── readme.md

更多好用插件推荐

相关文档

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android插件内部已配置无需再额外配置: <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: