Conversation
在 global.d.ts 文件中添加 WdGuide 组件的类型声明,确保 TypeScript 项目中可以正确识别该组件。 添加引导组件主逻辑
- 将 offset、borderRadius、padding、bottomSafetyOffset 和 topSafetyOffset 的类型从数组修改为 Number - 这种更改提高了类型定义的准确性和一致性,确保了更好的类型检查和代码质量
- 将 border-radius、padding、bottom-safety-offset 和 top-safety-offset 属性的类型从 string / number 修改为 number - 优化文档中属性类型的准确性,提高开发者体验
- 修改 highlightStyle 和 popoverStyle 计算属性,优化样式对象的创建方式 - 移除多余的空行和注释,提高代码整洁度 - 调整 updateElementInfo、getEffectiveBoundaries、checkScrollNeeds 等函数的结构,提升可读性 - 优化 scrollUp 和 scrollDown 函数中的变量赋值和注释
- 丰富了自定义功能,包括引导内容、高亮区域、按钮等 - 优化了引导步骤的控制逻辑,支持双向绑定当前步骤 - 调整了高亮区域和引导内容的样式,提升了用户体验 - 增加了组件的响应式处理,适应不同平台和屏幕尺寸 - 优化了代码结构,提高了组件的可维护性和可测试性
- 将 manifest.json 中的 appid 从 "wxf81518e7b11ea8d8" 更改为 "wx18107b71aa1672e2"
- 添加了向导组件的单元测试文件 - 实现了对向导组件各项功能的测试,包括基本渲染、隐藏状态、步骤内容渲染、按钮显示和功能、自定义文本和样式、事件触发等 - 模拟了 uni 对象和元素查询,以适应uni-app环境 wd-guide 去除多余的打印 修复menuButtonInfo的ts报错
- 移除了多处 console.log 调试日志,清理无用输出 - 为 menuButtonInfo 添加了更精确的类型定义 - 删除了未使用的计算属性 watch
- 提取公共的默认样式函数 getDefaultStyle - 提取公共的高亮样式计算函数 calculateHighlightStyle - 使用 computed 属性优化高亮样式和元素信息的计算 - 简化代码结构,提高可维护性和可读性
- 优化了引导组件的滚动逻辑,确保滚动到顶部后再显示引导步骤 - 添加了系统信息更新功能,提高元素定位的准确性 - 修复了某些场景下引导步骤显示异常的问题 - 优化了代码结构,提高了组件的可维护性 - 修复重复调用导致位置计算偏差问题
- 将 controlCurrent.value 的初始值从 6 修改为 2 - 优化了控制指南的起始步骤,提高了用户体验
- 将 guide 组件重命名为 tour 组件 - 更新了相关文件和代码中的 guide 引用,改为 tour - 调整了部分样式和命名以适应新的组件名称
- 移除旧的引导组件代码和文档 - 更新类型定义,使用通用的类型构造函数 - 优化组件属性定义,使用统一的类型创建方法 - 删除冗余的属性类型和默认值定义
- 将 guide-show 动画名称改为 tour-show,统一动画命名风格 - 此更改不影响功能,仅用于提升代码一致性和可维护性
- 新增中英文文档侧边栏目录 - 修改演示组件入口位置,确保导航一致性
- 调整标题结构,将“介绍”合并为描述文字,“基本用法”更名为“基本使用” - 统一代码块语言标识为 html,并更新 v-model 为 :model-value 以符合 Vue 3 写法 - 补充插槽、属性和方法的说明,优化自定义内容与样式的描述 - 规范化 props 类型标注,统一数值类属性类型为 number - 更新事件参数格式,移除冗余字段说明 - 更新本地化标题文本,保持中英文一致
- 在 H5 环境中使用 useLockScroll 返回的 lock 和 unlock 方法以正确控制滚动锁定 - 为 popoverStyle 增加更精确的 TypeScript 类型定义,提升代码可维护性 - 新增对 useLockScroll 的 mock 实现,完善组件单元测试覆盖
该提交移除了 `src/subPages/tour/index.vue` 文件中的所有内容,包括模板、脚本和样式部分。这可能是因为该页面不再需要,或其功能已被迁移至其他位置。
- 新增 filterable 属性支持本地和远程搜索功能 - 新增 refresher-enabled 属性支持下拉刷新 - 新增 scroll-to-lower-enabled 属性支持上拉加载更多 - 新增 search、refresh、scroll-to-lower 等事件 - 新增 stopRefresh 等方法 - 新增搜索和空数据插槽 - 添加本地搜索和远程搜索示例文档 - 添加下拉刷新和上拉加载示例文档 - 添加综合案例展示搜索+刷新+加载功能
移除了 getCurrentColData 和 getAllColData 方法的文档说明, 这些方法已在组件中移除。
- 在文档导航中添加 DragSort 拖拽排序组件链接 - 添加英文和中文国际化配置 - 配置页面路由和导航标题 - 在首页组件列表中注册新组件 - 在全局类型定义中声明组件类型
- 在中文文档导航中添加DragSort拖拽排序组件链接 - 添加国际化词条:en-US.json和zh-CN.json中的dragSort翻译 - 配置pages.json注册dragSort页面路径和样式设置 - 在首页组件中注册dragSort组件入口 - 在全局类型定义中声明WdDragSort、WdDragSortItem和WdDragHandle组件类型
✅ Deploy Preview for wot-design-uni ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
漫游高阶概述该PR引入了两个新组件(Tour和DragSort)以及一个辅助组件(DragHandle),同时显著扩展了ColPicker的功能,增加了搜索、刷新和无限滚动支持。包括完整的类型定义、样式、多语言支持、文档和演示页面。 变更
序列图sequenceDiagram
participant User as 用户
participant DragSort as DragSort<br/>主容器
participant Item as DragSortItem<br/>拖拽项
participant Handle as DragHandle<br/>拖拽句柄
participant Utils as 工具函数<br/>布局计算
User->>Item: 触摸项目
Item->>Item: 识别是否需要<br/>长按或手柄触发
alt 使用拖拽句柄
User->>Handle: 触摸句柄
Handle->>Item: onHandleTouch
else 直接触摸项
Item->>Item: 启动长按计时
end
Item->>DragSort: onDragStart事件
DragSort->>Utils: dragInit布局<br/>计算所有项目位置
Utils-->>DragSort: 返回items和slots
DragSort->>DragSort: 显示占位符<br/>startAutoScroll
User->>Item: 拖拽项目移动
Item->>DragSort: onDragMove<br/>提供位置数据
DragSort->>Utils: findClosestSlot<br/>找到最近的目标位置
alt 实时模式
DragSort->>DragSort: 立即排序<br/>更新modelValue
else 延迟模式
DragSort->>DragSort: 存储dragDelta<br/>延迟更新
end
DragSort->>DragSort: 更新currentSlotStyle<br/>占位符位置
User->>Item: 释放触摸
Item->>DragSort: onDragEnd事件
DragSort->>Utils: 最终位置验证<br/>确定最终排序
DragSort->>DragSort: 发出change和<br/>update:modelValue事件
DragSort->>DragSort: 重新初始化布局
sequenceDiagram
participant User as 用户
participant ColPicker as ColPicker<br/>列选择器
participant Search as 搜索栏<br/>wd-search
participant API as 远程API/本地数据
User->>ColPicker: 启用filterable=true
ColPicker->>Search: 显示搜索输入框
User->>Search: 输入搜索文本
Search->>ColPicker: handleSearchChange事件
alt 本地搜索(local)
ColPicker->>ColPicker: 过滤当前列数据<br/>显示匹配项
else 远程搜索(remote)
ColPicker->>ColPicker: 发出search-change事件
ColPicker->>API: 外部应用处理<br/>远程搜索请求
API-->>ColPicker: 返回过滤结果
ColPicker->>ColPicker: 更新列数据
end
User->>ColPicker: 下拉刷新(refresher)
ColPicker->>ColPicker: 发出refresh事件
API->>API: 重新加载数据
API-->>ColPicker: 返回新数据
User->>ColPicker: 上拉到底部
ColPicker->>ColPicker: 发出scroll-to-lower事件
API->>API: 加载更多数据<br/>(分页)
API-->>ColPicker: 返回下一批数据
ColPicker->>ColPicker: 追加到列表
代码审查工作量评估🎯 4 (复杂) | ⏱️ ~70 分钟 可能相关的PR
建议的审阅者
诗歌
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 15
🤖 Fix all issues with AI agents
In `@docs/component/col-picker.md`:
- Around line 934-938: The methods table has inconsistent column counts: the
rows for "open" and "close" are missing the "最低版本" cell; update the table so
each row has four columns (方法名称, 说明, 参数, 最低版本) by adding the missing cell (e.g.
"-" or the correct version) for the "open" and "close" rows so they match the
"stopRefresh" row and keep the table aligned.
- Around line 892-900: The properties table contains duplicate rows for
refresher-background and refresher-default-style; remove the duplicated entries
so each property appears only once, keeping the single correct row for
refresher-default-style (with allowed values 'black' / 'white' / 'none' and
default 'white') and the single correct row for refresher-background (default
'transparent'), and ensure the remaining table rows are reordered/aligned
consistently with the other properties (use the existing property names
refresher-default-style and refresher-background to locate the duplicates).
In `@docs/component/drag-sort.md`:
- Around line 193-198: The scroll-lock flag is inverted: when pointerEvents uses
`canScrollY ? 'auto' : 'none'`, dragging should disable scrolling; update
handleDragStart to set canScrollY.value = false and handleDragEnd to set
canScrollY.value = true so dragging disables pointer scroll and releasing
restores it; locate the canScrollY variable and the
handleDragStart/handleDragEnd functions to make this swap.
In `@docs/component/tour.md`:
- Around line 186-187: Update the event parameter type for `isUp` in the tour
component docs: change `isUp: number` to `isUp: boolean` in both the `prev` and
`next` table rows (the two entries showing `{ oldCurrent: number, current:
number, total: number, isUp: number }`) so the event signature becomes `{
oldCurrent: number, current: number, total: number, isUp: boolean }`.
- Line 1: 文档标题与组件命名不一致:当前 docs/component/tour.md 标题为 "Guide 漫游组件",但组件名为
`wd-tour` 且其它资源(如 locale 文件)使用 "Tour 漫游"。请将文档标题统一为与组件名和 locale 一致的表述(例如 "Tour
漫游" 或 "Tour 漫游引导"),并在文件头部(当前标题行)替换为选定的统一名称,同时检查并同步任何引用 `wd-tour` 的文档段落或示例以保持一致性。
In `@src/pages.json`:
- Around line 1346-1357: The non-MP navigationBarTitleText for the "dragSort"
page is hardcoded and should be replaced with an i18n placeholder to match other
pages; update the style entry under "name": "dragSort" (the
"navigationBarTitleText" in the // `#ifndef` MP block) to the appropriate locale
key placeholder (e.g. use the same key pattern used elsewhere like
"pages.dragSort.title" or the project's existing key for DragSort) so the title
is resolved via the i18n system instead of a literal string.
In `@src/subPages/colPicker/Index.vue`:
- Around line 535-539: The uni.showLoading calls are passing an invalid icon
option (icon: 'none'); update every occurrence of uni.showLoading in Index.vue
to only pass supported options (title and mask) and remove the icon property, or
if you intended a toast with an icon use uni.showToast instead (look for the
uni.showLoading invocations to modify). Ensure all instances reported (the three
additional occurrences) are fixed consistently.
- Around line 623-627: The DB array declared inside getComplexMockData (const
DB: any[] = []) is never used and should be removed to avoid dead code; remove
the DB declaration (and any related unused TOTAL_COUNT if it's solely for DB)
and keep the existing logic that generates rows into fullTable, ensuring
getComplexMockData only defines and returns fullTable and any genuinely used
constants like TOTAL_COUNT if referenced elsewhere.
In `@src/uni_modules/wot-design-uni/components/wd-col-picker/types.ts`:
- Line 1: Remove the unused named import handleError from the vue import
statement in types.ts; update the import to only include the used symbols
(ComponentPublicInstance, ExtractPropTypes, PropType) and verify there are no
remaining references to handleError in the file before committing.
In `@src/uni_modules/wot-design-uni/components/wd-col-picker/wd-col-picker.vue`:
- Around line 642-645: The function stopRefresh currently contains a console.log
debug statement; remove the console.log call from stopRefresh (which sets
refreshTriggered.value = false) so no console output remains in production, or
replace it with a noop or a controlled logger if a trace is required (refer to
stopRefresh and refreshTriggered in wd-col-picker.vue).
- Around line 113-117: Replace the hardcoded Chinese string for the empty state
by calling the existing translate() function: update the wd-status-tip usage in
the template v-else to pass the translated value (replace tip="暂无内容" with a
translate call) and add the corresponding "empty" key to the component's locale
files so translations resolve; refer to the existing translate() usages in this
component to mirror how they call translate().
In
`@src/uni_modules/wot-design-uni/components/wd-drag-sort-item/wd-drag-sort-item.vue`:
- Line 61: The module-level variable isHandleTriggered causes shared state
across wd-drag-sort-item instances; move its declaration into the component
instance (e.g. inside setup() as a ref or inside data() as a reactive property)
and replace all uses of isHandleTriggered with the instance-scoped reactive
(using .value if you choose ref) so each wd-drag-sort-item has its own trigger
flag; update any handlers/readers in the component to reference the new
instance-scoped symbol instead of the top-level isHandleTriggered.
In `@src/uni_modules/wot-design-uni/components/wd-tour/types.ts`:
- Around line 1-2: 导出类型 TourProps 当前使用 typeof tourProps(取到的是 props
定义对象)会导致错误的类型提示;请将导出改为使用 Vue 的 ExtractPropTypes 来提取解析后的 props 类型:在此文件中替换现有
TourProps 导出,引用 tourProps(props 定义对象)并用 ExtractPropTypes<typeof tourProps>
作为导出类型,确保导出的类型名仍为 TourProps 以保持向后兼容性。
In `@src/uni_modules/wot-design-uni/components/wd-tour/wd-tour.vue`:
- Around line 416-429: The watch handler for props.modelValue sets
oldscrollTop.value = 0 which breaks subsequent position calculations; instead,
when the tour opens (inside the watch callback where updateSystemInfo(),
nextTick(), and updateElementInfo() are called), read the current viewport
scroll via uni.createSelectorQuery().selectViewport().scrollOffset() and assign
that value to oldscrollTop.value before calling updateElementInfo() and emitting
update:current; keep updateSystemInfo() as is but replace the hardcoded 0
assignment with the actual scrollTop so scrollDistance calculations
(oldscrollTop.value + res.top - props.padding) use the correct baseline.
In `@tests/components/wd-tour.test.ts`:
- Line 175: Remove the template placeholder comment "// ... existing code ..."
from the test file (the placeholder present in tests/components/wd-tour.test.ts)
— delete that line and either replace it with the intended test code or leave no
stray placeholder comments so the test file contains only real test logic and
assertions (look for the exact string "// ... existing code ..." to locate and
remove it).
🧹 Nitpick comments (20)
.hbuilderx/launch.json (1)
1-9: 考虑是否应将 IDE 配置文件纳入版本控制配置文件本身格式正确且有效。但
.hbuilderx/目录是 HBuilderX IDE 的特定配置,通常这类 IDE 配置文件会被添加到.gitignore中,因为不同开发者可能有不同的 IDE 设置偏好。不过,如果团队希望统一开发环境配置以提高一致性,提交此文件也是合理的。建议与团队确认项目约定。
src/subPages/dragSort/Index.vue (1)
391-396: 建议同步滚动状态,避免拖拽后跳动。
handleScroll只更新currentScrollTop,scrollTop仅在onScroll更新。若程序化滚动未触发scroll事件,scrollTop可能不同步。建议在自动滚动时同步两者并钳制到非负。♻️ 建议修改
function onScroll(e: any) { - scrollTop.value = e.detail.scrollTop + const top = e.detail.scrollTop + scrollTop.value = top + currentScrollTop.value = top } function handleScroll({ dy }: { dx: number; dy: number }) { - currentScrollTop.value += dy + const next = Math.max(0, currentScrollTop.value + dy) + currentScrollTop.value = next + scrollTop.value = next }src/locale/zh-CN.json (2)
416-416: 键名dragSort位置破坏了字母排序顺序。该文件中的键名按字母顺序排列,
dragSort应该放在d开头的其他键附近(如down-and-load-more之后),而不是在duo-xuan之后。
971-971: 键名remote_down-and-load-more使用下划线,与其他键名的连字符命名约定不一致。其他类似的键名如
down-and-load-more、remote-search都使用连字符。建议改为remote-down-and-load-more以保持一致性。tests/components/wd-tour.test.ts (2)
123-123: 考虑将超时魔数提取为常量。多处使用
100、150等超时值,建议提取为常量以提高可维护性和 CI 环境下的稳定性:const DOM_UPDATE_DELAY = 100 const EXTENDED_DOM_DELAY = 150Also applies to: 142-142, 162-162, 192-192, 209-209, 225-225
59-81:beforeEach中的 mock 实现与模块级定义重复。
mockUni.createSelectorQuery.mockImplementation在 lines 14-40 已定义,beforeEach中再次定义相同实现是冗余的。vi.clearAllMocks()和mockClear()已足够重置状态。简化 beforeEach
beforeEach(() => { vi.clearAllMocks() - // 重置模拟函数 - mockUni.createSelectorQuery.mockClear() - mockUni.createSelectorQuery.mockImplementation(() => ({ - select: vi.fn(() => ({ - boundingClientRect: vi.fn((callback) => { - // 模拟元素位置信息 - setTimeout(() => { - callback({ - top: 100, - left: 50, - width: 200, - height: 100 - }) - }, 10) - return { - exec: vi.fn() - } - }) - })) - })) })src/uni_modules/wot-design-uni/components/wd-drag-sort/types.ts (2)
2-2:makeArrayProp已导入但未使用。建议移除未使用的导入以保持代码整洁。
移除未使用的导入
-import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props' +import { baseProps, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
30-37:DragSortProvide中的函数参数类型较宽松。
touch: any、helper: any等参数使用any类型,降低了类型安全性。如果有明确的 touch event 或 helper 接口定义,建议替换为具体类型。src/subPages/tour/Index.vue (2)
182-182:watch已导入但未使用。建议移除未使用的导入。
移除未使用的导入
-import { ref, watch, nextTick } from 'vue' +import { ref, nextTick } from 'vue'
315-338: 启动引导的函数对scrollToTop()的处理不一致。
startBasicTour使用await scrollToTop()和nextTick,而其他函数(如startMaskNextTour、startNoMaskTour等)直接调用scrollToTop()但不等待其完成。这可能导致滚动未完成时引导就开始显示。建议统一异步处理
-function startMaskNextTour() { - scrollToTop() - showClickMaskTour.value = true -} +async function startMaskNextTour() { + await scrollToTop() + nextTick(() => { + showClickMaskTour.value = true + }) +}其他函数也应采用类似模式。
src/subPages/colPicker/Index.vue (1)
766-771: 存在两个onMounted钩子。文件中有两处
onMounted(lines 129-139 和 766-771)。虽然 Vue 允许多个onMounted,但合并到一处更易维护。建议合并 onMounted 钩子
onMounted(async () => { toast.loading(t('shu-ju-jia-zai-zhong')) await sleep() toast.close() value2.value = ['150000', '150100', '150121'] getMockData(0, 1).then((data) => { columnsAsync.value = [data] pageMap.value[0] = 1 }) + + // 初始化综合案例第一列数据 + pageMapComplex.value[0] = 1 + getComplexMockData(0, 1).then((data) => { + columnsComplex.value = [data] + }) }) - -// 初始化综合案例第一列数据 -onMounted(() => { - pageMapComplex.value[0] = 1 - getComplexMockData(0, 1).then((data) => { - columnsComplex.value = [data] - }) -})src/uni_modules/wot-design-uni/components/wd-drag-sort-item/wd-drag-sort-item.vue (3)
49-49:slots变量声明后未使用。
useSlots()被调用但返回值未被使用,建议移除。移除未使用的代码
-const slots = useSlots()同时从 import 中移除
useSlots:-import { ref, computed, watch, onMounted, getCurrentInstance, onBeforeUnmount, useSlots } from 'vue' +import { ref, computed, watch, onMounted, getCurrentInstance, onBeforeUnmount } from 'vue'
178-183:init()函数体为空,仅包含注释。函数声明后实际没有执行任何操作,且
onMounted中调用了它。如果不需要此函数,建议移除相关代码以避免混淆。
209-209: 存在注释掉的代码。
// let touchStartTime = 0是死代码,如果确认不需要应该删除。建议移除
let longPressTimer: ReturnType<typeof setTimeout> | null = null let touchStartPosition = { x: 0, y: 0 } -// let touchStartTime = 0src/uni_modules/wot-design-uni/components/wd-drag-sort/utils.ts (3)
7-16: 与common/util.ts中的throttle函数存在重复。根据提供的代码片段,
common/util.ts中已经有一个更完整的throttle实现,支持尾部调用(trailing edge)。当前实现更简单,会丢弃延迟期间的最后一次调用。建议考虑复用现有的
throttle函数,或者在此处添加注释说明为什么需要这种简化的实现(例如:拖拽场景不需要尾部调用)。
78-84:swapArrayItem函数的行为与注释描述不一致。注释声明返回"同一引用"(
返回同一引用),但函数实际上直接修改了传入的数组。这种原地修改可能会导致调用方意外地改变原始数据。与
moveArrayItem(返回新数组)的行为不一致,建议统一为不可变操作:♻️ 建议修改为不可变操作
export const swapArrayItem = (arr: any[], fromIndex: number, toIndex: number) => { - if (fromIndex === toIndex) return arr // 同一个位置啥也不做 - const temp = arr[fromIndex] - arr[fromIndex] = arr[toIndex] - arr[toIndex] = temp - return arr + if (fromIndex === toIndex) return [...arr] + const newArr = [...arr] + ;[newArr[fromIndex], newArr[toIndex]] = [newArr[toIndex], newArr[fromIndex]] + return newArr }
129-134: 使用了已弃用的substr方法。
String.prototype.substr已被标记为弃用,建议使用substring或slice替代。♻️ 建议修改
export const generateId = (prefix = 'ds') => { // 使用时间戳 + 随机数生成 ID,兼容小程序环境 const timestamp = Date.now().toString(36) - const random = Math.random().toString(36).substr(2, 5) + const random = Math.random().toString(36).substring(2, 7) return `${prefix}_${timestamp}${random}` }src/uni_modules/wot-design-uni/components/wd-drag-sort/wd-drag-sort.vue (3)
278-283:reset函数已定义但从未使用。此函数在组件内部没有被调用,也未通过
defineExpose暴露给外部。如果不需要,建议移除以避免死代码。🧹 如果不需要,建议移除
-/** - * 重置状态,强制重新计算 - */ -const reset = () => { - isReady.value = false - for (const key in items) { - delete items[key] - } -}或者,如果此函数有公共用途,可以将其添加到
defineExpose中:defineExpose({ - init: dragInit + init: dragInit, + reset })
139-145: 重试计数器附加在函数对象上的模式不够清晰。当前将
retryCount附加到dragInit函数对象上,虽然能工作,但可读性较差且需要类型断言。建议使用ref管理重试计数。♻️ 建议使用 ref 管理重试计数
+const retryCount = ref(0) + const retryLayout = () => { - if (!(dragInit as any).retryCount) (dragInit as any).retryCount = 0 - if ((dragInit as any).retryCount < 3) { - ;(dragInit as any).retryCount++ + if (retryCount.value < 3) { + retryCount.value++ setTimeout(() => dragInit(), 50) } }同时在
handleLayout成功时重置:- ;(dragInit as any).retryCount = 0 // 成功后重置重试计数 + retryCount.value = 0 // 成功后重置重试计数
56-71:linkChildren中的register/unregister为空函数。注释说明
useChildren不需要这两个方法,但仍然提供了空实现。如果确实不需要,建议移除以简化代码;如果是为了接口兼容,建议添加更详细的注释说明。
| | filterable | 是否开启搜索功能(本地/远程) | boolean | - | false | - | | ||
| | filter-type | 搜索类型:'local' (本地过滤) 或 'remote' (远程搜索) | string | - | 'local' | - | | ||
| | filter-placeholder | 搜索输入框占位符 | string | - | - | - | | ||
| | refresher-enabled | 是否开启下拉刷新 | boolean | - | false | - | | ||
| | refresher-default-style| 下拉刷新默认样式 | string | 'black' / 'white' / 'none' | 'white' | - | | ||
| | refresher-background | 下拉刷新区域背景颜色 | string | - | transparent | - | | ||
| | scroll-to-lower-enabled| 是否开启上拉加载更多 | boolean | - | false | - | | ||
| | refresher-background | 下拉刷新区域背景颜色 | string | - | transparent | - | | ||
| | refresher-default-style| 下拉刷新默认样式 | string | 'black' / 'white' / 'none' | 'white' | - | |
There was a problem hiding this comment.
属性表重复行会导致文档歧义。
refresher-background 与 refresher-default-style 在表内重复出现,请保留一组即可。
🛠️ 建议修改
-| refresher-background | 下拉刷新区域背景颜色 | string | - | transparent | - |
-| refresher-default-style| 下拉刷新默认样式 | string | 'black' / 'white' / 'none' | 'white' | - |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | filterable | 是否开启搜索功能(本地/远程) | boolean | - | false | - | | |
| | filter-type | 搜索类型:'local' (本地过滤) 或 'remote' (远程搜索) | string | - | 'local' | - | | |
| | filter-placeholder | 搜索输入框占位符 | string | - | - | - | | |
| | refresher-enabled | 是否开启下拉刷新 | boolean | - | false | - | | |
| | refresher-default-style| 下拉刷新默认样式 | string | 'black' / 'white' / 'none' | 'white' | - | | |
| | refresher-background | 下拉刷新区域背景颜色 | string | - | transparent | - | | |
| | scroll-to-lower-enabled| 是否开启上拉加载更多 | boolean | - | false | - | | |
| | refresher-background | 下拉刷新区域背景颜色 | string | - | transparent | - | | |
| | refresher-default-style| 下拉刷新默认样式 | string | 'black' / 'white' / 'none' | 'white' | - | | |
| | filterable | 是否开启搜索功能(本地/远程) | boolean | - | false | - | | |
| | filter-type | 搜索类型:'local' (本地过滤) 或 'remote' (远程搜索) | string | - | 'local' | - | | |
| | filter-placeholder | 搜索输入框占位符 | string | - | - | - | | |
| | refresher-enabled | 是否开启下拉刷新 | boolean | - | false | - | | |
| | refresher-default-style| 下拉刷新默认样式 | string | 'black' / 'white' / 'none' | 'white' | - | | |
| | refresher-background | 下拉刷新区域背景颜色 | string | - | transparent | - | | |
| | scroll-to-lower-enabled| 是否开启上拉加载更多 | boolean | - | false | - | |
🤖 Prompt for AI Agents
In `@docs/component/col-picker.md` around lines 892 - 900, The properties table
contains duplicate rows for refresher-background and refresher-default-style;
remove the duplicated entries so each property appears only once, keeping the
single correct row for refresher-default-style (with allowed values 'black' /
'white' / 'none' and default 'white') and the single correct row for
refresher-background (default 'transparent'), and ensure the remaining table
rows are reordered/aligned consistently with the other properties (use the
existing property names refresher-default-style and refresher-background to
locate the duplicates).
| | 方法名称 | 说明 | 参数 | 最低版本 | | ||
| | -------- | ---------------- | ---- | -------- | | ||
| | open | 打开 picker 弹框 | - | | ||
| | close | 关闭 picker 弹框 | - | | ||
| | stopRefresh | 停止下拉刷新 | - | - | |
There was a problem hiding this comment.
Methods 表格列数不一致。
open/close 行缺少“最低版本”列,导致表格列数不一致。
🛠️ 建议修改
-| open | 打开 picker 弹框 | - |
-| close | 关闭 picker 弹框 | - |
+| open | 打开 picker 弹框 | - | - |
+| close | 关闭 picker 弹框 | - | - |🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 936-936: Table column count
Expected: 4; Actual: 3; Too few cells, row will be missing data
(MD056, table-column-count)
[warning] 937-937: Table column count
Expected: 4; Actual: 3; Too few cells, row will be missing data
(MD056, table-column-count)
🤖 Prompt for AI Agents
In `@docs/component/col-picker.md` around lines 934 - 938, The methods table has
inconsistent column counts: the rows for "open" and "close" are missing the
"最低版本" cell; update the table so each row has four columns (方法名称, 说明, 参数, 最低版本)
by adding the missing cell (e.g. "-" or the correct version) for the "open" and
"close" rows so they match the "stopRefresh" row and keep the table aligned.
| const handleDragStart = (index) => { | ||
| canScrollY.value = true | ||
| } | ||
| const handleDragEnd = (index) => { | ||
| canScrollY.value = false | ||
| } |
There was a problem hiding this comment.
滚动锁定示例的 canScrollY 取值反了。
pointerEvents: canScrollY ? 'auto' : 'none' 时,拖拽开始应禁用滚动(false),结束后恢复(true)。
🛠️ 建议修改
const handleDragStart = (index) => {
- canScrollY.value = true
+ canScrollY.value = false
}
const handleDragEnd = (index) => {
- canScrollY.value = false
+ canScrollY.value = true
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleDragStart = (index) => { | |
| canScrollY.value = true | |
| } | |
| const handleDragEnd = (index) => { | |
| canScrollY.value = false | |
| } | |
| const handleDragStart = (index) => { | |
| canScrollY.value = false | |
| } | |
| const handleDragEnd = (index) => { | |
| canScrollY.value = true | |
| } |
🤖 Prompt for AI Agents
In `@docs/component/drag-sort.md` around lines 193 - 198, The scroll-lock flag is
inverted: when pointerEvents uses `canScrollY ? 'auto' : 'none'`, dragging
should disable scrolling; update handleDragStart to set canScrollY.value = false
and handleDragEnd to set canScrollY.value = true so dragging disables pointer
scroll and releasing restores it; locate the canScrollY variable and the
handleDragStart/handleDragEnd functions to make this swap.
| @@ -0,0 +1,254 @@ | |||
| # Guide 漫游组件 | |||
There was a problem hiding this comment.
标题命名不一致。
文档标题为 "Guide 漫游组件",但组件名为 wd-tour,其他地方(如 locale 文件)使用 "Tour 漫游"。建议统一为 "Tour 漫游" 或 "Tour 漫游引导"。
建议修复
-# Guide 漫游组件
+# Tour 漫游引导📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Guide 漫游组件 | |
| # Tour 漫游引导 |
🤖 Prompt for AI Agents
In `@docs/component/tour.md` at line 1, 文档标题与组件命名不一致:当前 docs/component/tour.md 标题为
"Guide 漫游组件",但组件名为 `wd-tour` 且其它资源(如 locale 文件)使用 "Tour 漫游"。请将文档标题统一为与组件名和
locale 一致的表述(例如 "Tour 漫游" 或 "Tour 漫游引导"),并在文件头部(当前标题行)替换为选定的统一名称,同时检查并同步任何引用
`wd-tour` 的文档段落或示例以保持一致性。
| | prev | 点击上一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: number }` | | ||
| | next | 点击下一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: number }` | |
There was a problem hiding this comment.
事件参数 isUp 的类型应为 boolean 而非 number。
根据语义,isUp 表示方向(向上/向下),应该是布尔值类型。
建议修复
-| prev | 点击上一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: number }` |
-| next | 点击下一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: number }` |
+| prev | 点击上一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: boolean }` |
+| next | 点击下一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: boolean }` |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | prev | 点击上一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: number }` | | |
| | next | 点击下一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: number }` | | |
| | prev | 点击上一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: boolean }` | | |
| | next | 点击下一步按钮时触发 | `{ oldCurrent: number, current: number, total: number, isUp: boolean }` | |
🤖 Prompt for AI Agents
In `@docs/component/tour.md` around lines 186 - 187, Update the event parameter
type for `isUp` in the tour component docs: change `isUp: number` to `isUp:
boolean` in both the `prev` and `next` table rows (the two entries showing `{
oldCurrent: number, current: number, total: number, isUp: number }`) so the
event signature becomes `{ oldCurrent: number, current: number, total: number,
isUp: boolean }`.
| function stopRefresh() { | ||
| refreshTriggered.value = false | ||
| console.log('[wd-col-picker] 停止刷新状态') | ||
| } |
There was a problem hiding this comment.
移除调试日志语句。
console.log 不应出现在生产代码中。
🧹 建议移除
function stopRefresh() {
refreshTriggered.value = false
- console.log('[wd-col-picker] 停止刷新状态')
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function stopRefresh() { | |
| refreshTriggered.value = false | |
| console.log('[wd-col-picker] 停止刷新状态') | |
| } | |
| function stopRefresh() { | |
| refreshTriggered.value = false | |
| } |
🤖 Prompt for AI Agents
In `@src/uni_modules/wot-design-uni/components/wd-col-picker/wd-col-picker.vue`
around lines 642 - 645, The function stopRefresh currently contains a
console.log debug statement; remove the console.log call from stopRefresh (which
sets refreshTriggered.value = false) so no console output remains in production,
or replace it with a noop or a controlled logger if a trace is required (refer
to stopRefresh and refreshTriggered in wd-col-picker.vue).
| // 同步的样式 | ||
| const syncedStyle = ref({}) | ||
| // 是否由 handle 触发拖拽 | ||
| let isHandleTriggered = false |
There was a problem hiding this comment.
isHandleTriggered 作为模块级变量可能导致多实例共享状态问题。
let isHandleTriggered = false 不是响应式的,且在模块级别声明。如果页面上有多个 wd-drag-sort-item 实例,它们会共享这个变量,可能导致拖拽行为异常。
建议改为 ref 或在组件实例范围内声明。
建议修复
-// 是否由 handle 触发拖拽
-let isHandleTriggered = false
+// 是否由 handle 触发拖拽
+const isHandleTriggered = ref(false)然后更新使用处:
- if (parent && parent.props.useDragHandle && !isHandleTriggered) {
+ if (parent && parent.props.useDragHandle && !isHandleTriggered.value) {
return
}
// 重置标志位
- isHandleTriggered = false
+ isHandleTriggered.value = false const onHandleTouch = (e: any) => {
if (parent && parent.props.useDragHandle) {
- isHandleTriggered = true
+ isHandleTriggered.value = true
startDragLogic(e)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let isHandleTriggered = false | |
| // 是否由 handle 触发拖拽 | |
| const isHandleTriggered = ref(false) |
🤖 Prompt for AI Agents
In
`@src/uni_modules/wot-design-uni/components/wd-drag-sort-item/wd-drag-sort-item.vue`
at line 61, The module-level variable isHandleTriggered causes shared state
across wd-drag-sort-item instances; move its declaration into the component
instance (e.g. inside setup() as a ref or inside data() as a reactive property)
and replace all uses of isHandleTriggered with the instance-scoped reactive
(using .value if you choose ref) so each wd-drag-sort-item has its own trigger
flag; update any handlers/readers in the component to reference the new
instance-scoped symbol instead of the top-level isHandleTriggered.
| import type { PropType } from 'vue' | ||
| import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp, makeArrayProp } from '../common/props' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's read the types.ts file to see the current state
cat -n "src/uni_modules/wot-design-uni/components/wd-tour/types.ts"Repository: Moonofweisheng/wot-design-uni
Length of output: 3350
🌐 Web query:
Vue 3 ExtractPropTypes vs typeof props type extraction best practices
💡 Result:
What each approach is for
ExtractPropTypes<typeof propsOptions>
Use this when you declare runtime props as an options object and you want a reusable type derived from that object. Vue documents ExtractPropTypes as internal-facing / resolved props (e.g., booleans and props with defaults are treated as always defined). Use ExtractPublicPropTypes when you want the public-facing type (what parents are allowed to pass). [1]
import type { ExtractPropTypes, ExtractPublicPropTypes } from 'vue'
export const propsOptions = {
foo: String,
bar: Boolean,
qux: { type: Number, default: 1 },
baz: { type: Number, required: true },
} as const
export type MyPropsResolved = ExtractPropTypes<typeof propsOptions>
export type MyPropsPublic = ExtractPublicPropTypes<typeof propsOptions>typeof props (where const props = defineProps(...))
Use this when you already have the props variable and you just need the type locally (or to derive helper types), e.g.:
const props = defineProps<Props>()
type LocalProps = typeof propsThis is usually not the best “exported API” type, because it ties the type to a particular variable and (depending on how you declared props) represents the component’s resolved props shape rather than “what a parent can pass”.
Best-practice recommendations (Vue 3)
- If you’re using type-based props (
defineProps<Props>()): exportPropsdirectly (or import it where needed). You don’t need extraction utilities in this case. [8] - If you’re using runtime props options (
defineProps(propsOptions)/props: { ... }):- use
ExtractPublicPropTypes<typeof propsOptions>for “parent can pass” types, and - use
ExtractPropTypes<typeof propsOptions>for “component receives” (resolved) types. [1]
- use
- Don’t mix runtime and type-based declarations at the same time—Vue explicitly calls out that you must choose one or the other. [8]
- Prefer
ExtractPublicPropTypeswhen documenting/typing a component’s external interface, especially when defaults/boolean props are involved (becauseExtractPropTypesintentionally models them as always-defined). [1]
Rule of thumb:
- “I want the component’s public props contract” →
ExtractPublicPropTypesfrom apropsOptionsobject. [1] - “I’m inside the component and want the resolved props” →
ExtractPropTypes(or just rely onpropsinference). [1] - “I used
defineProps<Props>()” → export/useProps(don’t extract). [8]
Sources: Vue Utility Types (ExtractPropTypes / ExtractPublicPropTypes) [1], Vue TypeScript + Composition API guide (choose runtime OR type-based; exporting/importing Props) [8].
修正 TourProps 类型导出以提供正确的 TypeScript 类型提示。
第 153 行使用 typeof tourProps 导出的是 props 定义对象的类型,而非组件实际接收的已解析 props 类型。这会导致 TypeScript 使用方获得不准确的类型提示。应改为 ExtractPropTypes<typeof tourProps>,这符合 Vue 3 官方推荐的最佳实践。
修复方案
-import type { PropType } from 'vue'
+import type { PropType, ExtractPropTypes } from 'vue'-export type TourProps = typeof tourProps
+export type TourProps = ExtractPropTypes<typeof tourProps>🤖 Prompt for AI Agents
In `@src/uni_modules/wot-design-uni/components/wd-tour/types.ts` around lines 1 -
2, 导出类型 TourProps 当前使用 typeof tourProps(取到的是 props 定义对象)会导致错误的类型提示;请将导出改为使用 Vue
的 ExtractPropTypes 来提取解析后的 props 类型:在此文件中替换现有 TourProps 导出,引用 tourProps(props
定义对象)并用 ExtractPropTypes<typeof tourProps> 作为导出类型,确保导出的类型名仍为 TourProps 以保持向后兼容性。
| // 监听 modelValue 变化,当组件显示时更新系统信息 | ||
| watch( | ||
| () => props.modelValue, | ||
| (newVal) => { | ||
| if (newVal) { | ||
| // 组件显示时重置滚动位置并更新系统信息 | ||
| oldscrollTop.value = 0 | ||
| updateSystemInfo() | ||
| nextTick(() => { | ||
| setTimeout(() => { | ||
| updateElementInfo() | ||
| emit('update:current', currentIndex.value) | ||
| }, 50) | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find the wd-tour.vue file
find . -name "wd-tour.vue" -type fRepository: Moonofweisheng/wot-design-uni
Length of output: 136
🏁 Script executed:
# List the repository structure to understand the project layout
ls -la | head -20Repository: Moonofweisheng/wot-design-uni
Length of output: 1246
🏁 Script executed:
# Get the file size to determine how to read it
wc -l src/uni_modules/wot-design-uni/components/wd-tour/wd-tour.vue 2>/dev/null || find . -name "wd-tour.vue" -exec wc -l {} \;Repository: Moonofweisheng/wot-design-uni
Length of output: 138
🏁 Script executed:
# Read the relevant section around lines 416-429
sed -n '410,440p' src/uni_modules/wot-design-uni/components/wd-tour/wd-tour.vueRepository: Moonofweisheng/wot-design-uni
Length of output: 559
🏁 Script executed:
# Search for all occurrences of oldscrollTop and scrollOffset in the file
rg -n 'oldscrollTop|scrollOffset|pageScrollTo' src/uni_modules/wot-design-uni/components/wd-tour/wd-tour.vueRepository: Moonofweisheng/wot-design-uni
Length of output: 534
🏁 Script executed:
# Read more context around the pageScrollTo calls to understand the flow
sed -n '275,315p' src/uni_modules/wot-design-uni/components/wd-tour/wd-tour.vueRepository: Moonofweisheng/wot-design-uni
Length of output: 1392
🏁 Script executed:
# Search for selectViewport usage in the codebase
rg -n 'selectViewport' src/uni_modules/wot-design-uni/Repository: Moonofweisheng/wot-design-uni
Length of output: 55
🏁 Script executed:
# Check if there are scroll event listeners
rg -n 'onPageScroll|pageScroll|scroll' src/uni_modules/wot-design-uni/components/wd-tour/wd-tour.vueRepository: Moonofweisheng/wot-design-uni
Length of output: 1189
🌐 Web query:
uni-app selectViewport scrollOffset API documentation
💡 Result:
Official uni-app docs for selectViewport and scrollOffset are under API → UI → Node Info (uni.createSelectorQuery):
selectorQuery.selectViewport(): selects the viewport (visible area) so you can query its size/scroll info. [1]nodesRef.scrollOffset(cb): queries a node’s scroll position (scrollLeft,scrollTop); the node must be ascroll-vieworviewport. [1]- Alternative:
nodesRef.fields({ scrollOffset: true }, cb)to includescrollLeft/scrollTopin afields()result. [1][2]
Example from the docs:
uni.createSelectorQuery()
.selectViewport()
.scrollOffset((res) => {
// res.scrollTop / res.scrollLeft
})
.exec();[1]
Doc pages (official):
https://en.uniapp.dcloud.io/api/ui/nodes-info.html
https://uniapp.dcloud.net.cn/api/ui/nodes-info.html
[1][2]
Sources:
[1] uni-app (EN) Node Info / createSelectorQuery docs
[2] uni-app (CN) Node Info / createSelectorQuery docs
🌐 Web query:
uni-app pageScrollTo how to get current scroll position
💡 Result:
To get the current scroll position in uni-app (when using uni.pageScrollTo), you don’t “read it back” from pageScrollTo. Instead, track it via the page scroll event:
1) Page (window) scroll position
Use onPageScroll, which provides e.scrollTop (pixels scrolled vertically). (en.uniapp.dcloud.io)
Options API
export default {
data() {
return { scrollTop: 0 }
},
onPageScroll(e) {
this.scrollTop = e.scrollTop
},
methods: {
toTop() {
uni.pageScrollTo({ scrollTop: 0, duration: 300 })
}
}
}<script setup>
import { ref } from 'vue'
import { onPageScroll } from '@dcloudio/uni-app'
const scrollTop = ref(0)
onPageScroll((e) => {
scrollTop.value = e.scrollTop
})2) If you’re scrolling inside a scroll-view (not the page)
Listen to the scroll-view @scroll event, or query its scroll offset via createSelectorQuery().select(...).scrollOffset(...) (works for scroll-view/viewport). (en.uniapp.dcloud.io)
Citations:
- 1: https://en.uniapp.dcloud.io/tutorial/page.html?utm_source=openai
- 2: https://en.uniapp.dcloud.io/api/ui/nodes-info.html?utm_source=openai
打开已滚动页面时引导位置定位偏差。
当 tour 在已滚动的页面上打开时,设置 oldscrollTop.value = 0 会导致后续位置计算错误。由于 scrollDistance 计算依赖 oldscrollTop 作为基准(如 oldscrollTop.value + res.top - props.padding),若页面已滚动但 oldscrollTop 为 0,计算结果将偏离实际滚动距离,导致引导高亮或弹窗位置错位。
建议在打开时通过 uni.createSelectorQuery().selectViewport().scrollOffset() 读取当前滚动位置后再执行 updateElementInfo()。
🔧 建议在打开引导时读取当前 scrollTop
watch(
() => props.modelValue,
(newVal) => {
if (newVal) {
- // 组件显示时重置滚动位置并更新系统信息
- oldscrollTop.value = 0
- updateSystemInfo()
- nextTick(() => {
- setTimeout(() => {
- updateElementInfo()
- emit('update:current', currentIndex.value)
- }, 50)
- })
+ // 组件显示时先读取当前滚动位置再更新引导
+ updateSystemInfo()
+ uni.createSelectorQuery()
+ .selectViewport()
+ .scrollOffset((res: { scrollTop?: number }) => {
+ oldscrollTop.value = res?.scrollTop ?? 0
+ nextTick(() => {
+ setTimeout(() => {
+ updateElementInfo()
+ emit('update:current', currentIndex.value)
+ }, 50)
+ })
+ })
+ .exec()
}
},
{
immediate: true
}
)🤖 Prompt for AI Agents
In `@src/uni_modules/wot-design-uni/components/wd-tour/wd-tour.vue` around lines
416 - 429, The watch handler for props.modelValue sets oldscrollTop.value = 0
which breaks subsequent position calculations; instead, when the tour opens
(inside the watch callback where updateSystemInfo(), nextTick(), and
updateElementInfo() are called), read the current viewport scroll via
uni.createSelectorQuery().selectViewport().scrollOffset() and assign that value
to oldscrollTop.value before calling updateElementInfo() and emitting
update:current; keep updateSystemInfo() as is but replace the hardcoded 0
assignment with the actual scrollTop so scrollDistance calculations
(oldscrollTop.value + res.top - props.padding) use the correct baseline.
| expect(wrapper.find('.wd-tour__next').exists()).toBe(false) | ||
| expect(wrapper.find('.wd-tour__skip').exists()).toBe(true) | ||
| }) | ||
| // ... existing code ... |
There was a problem hiding this comment.
移除占位符注释。
// ... existing code ... 看起来是模板占位符,不应出现在最终代码中。
建议修复
- // ... existing code ...
-
// 测试自定义按钮文字🤖 Prompt for AI Agents
In `@tests/components/wd-tour.test.ts` at line 175, Remove the template
placeholder comment "// ... existing code ..." from the test file (the
placeholder present in tests/components/wd-tour.test.ts) — delete that line and
either replace it with the intended test code or leave no stray placeholder
comments so the test file contains only real test logic and assertions (look for
the exact string "// ... existing code ..." to locate and remove it).
|
@Xiabaiyou is attempting to deploy a commit to the weisheng's projects Team on Vercel. A member of the Team first needs to authorize it. |
🤔 这个 PR 的性质是?(至少选择一个)
🔗 相关 Issue
💡 需求背景和解决方案
☑️ 请求合并前的自查清单
Summary by CodeRabbit
发布说明
新功能
文档
多语言