diff --git a/.workbuddy/memory/MEMORY.md b/.workbuddy/memory/MEMORY.md index e69de29..fa5fa8f 100644 --- a/.workbuddy/memory/MEMORY.md +++ b/.workbuddy/memory/MEMORY.md @@ -0,0 +1,39 @@ +# websopy-taro 项目记忆 + +## Tailwind CSS 在小程序中的兼容性规则 + +以下 Tailwind 类名在 WXSS 中不兼容,项目内禁止使用,已通过 PostCSS 插件 `postcss-remove-wxss-incompatible.js` 自动移除对应的 CSS 规则: + +1. **`!xxx` important 修饰符**(如 `!visible`):生成 `.!visible` 选择器,WXSS 不支持反斜杠转义的 `!`。 + +2. **带 `0.5` 的类名**(如 `w-0.5`、`h-0.5`、`gap-0.5`):类名中的 `.` 被转义为 `\.`,生成 `.w-0\.5` 这样的选择器,WXSS 不兼容。应改用等效的整数尺寸或自定义值替代。 + +3. **`space-x-*` / `space-y-*`**(如 `space-y-4`):依赖 `:not()` + `~` 兄弟组合器 + CSS 变量 + 嵌套 `calc()`,WXSS 全不支持。应改用 `flex flex-col gap-*` 实现等效间距。 + +4. **`divide-x-*` / `divide-y-*`**:同样依赖 `:not()` + `~`,WXSS 不兼容。 + +## 替代方案速查 + +| 禁用类名 | 替代写法 | +|---------|---------| +| `space-y-4` | `flex flex-col gap-4` | +| `space-x-4` | `flex flex-row gap-4` | +| `!visible` | 直接写 `style={{ visibility: 'visible' }}` 或自定义类 | +| `w-0.5` | 用自定义值或 `w-1` 替代 | + +## 微信小程序接口合规 + +### 剪切板接口(运营规范 5.15.4) + +1. **只允许用户主动触发复制**:所有 `Taro.setClipboardData` 调用必须绑定在明确的用户点击事件上,禁止在无用户操作时自动读写剪切板。 +2. **禁止复制后强制中断流程**:复制成功后不得强制跳转、强制关注、强制添加客服等,不能要求用户通过其他方式才能完成当前业务流程。 +3. **避免重复 Toast 干扰体验**:微信小程序调用 `setClipboardData` 成功后系统会自带「内容已复制」提示。为避免重复提示,统一封装 `utils/common.ts` 中的 `copyText` 函数:小程序端不再额外显示自定义 `复制成功` Toast,失败时仍显示错误提示。 + +### 项目内剪切板使用现状 + +已审查所有 `setClipboardData` 调用: +- 均通过按钮点击触发(复制咨询模板、复制密钥、复制链接、复制兑换码等) +- 无 `getClipboardData`(自动读取剪切板)调用 +- 无复制后强制跳转或中断业务流程的行为 + +当前实现基本符合 5.15.4 规范。 diff --git a/postcss-remove-wxss-incompatible.js b/postcss-remove-wxss-incompatible.js new file mode 100644 index 0000000..62a117e --- /dev/null +++ b/postcss-remove-wxss-incompatible.js @@ -0,0 +1,46 @@ +/** + * PostCSS 插件:移除 WXSS 不兼容的 Tailwind CSS 规则 + * + * 微信小程序 WXSS 不支持以下 CSS 特性: + * 1. 反斜杠转义的特殊字符(如 .\!visible)—— !important 修饰符 + * 2. :not() 伪类 + ~ 兄弟选择器组合(如 .space-y-4 > :not([hidden]) ~ :not([hidden])) + * 3. CSS 自定义属性 / CSS 变量(如 --tw-space-y-reverse) + * 4. 嵌套 calc()(如 calc(0.5rem * calc(1 - var(--tw-space-y-reverse)))) + * + * 该插件移除以下类型的 Tailwind CSS 规则: + * - .\!xxx 类选择器(important 修饰符) + * - .space-[x|y]-* 规则(间距布局,依赖 :not + ~ + CSS 变量 + 嵌套 calc) + * - .divide-[x|y]-* 规则(分割线布局,同样依赖不兼容特性) + */ + +/** @type {import('postcss').PluginCreator} */ +module.exports = (options = {}) => { + return { + postcssPlugin: 'postcss-remove-wxss-incompatible', + Rule(rule) { + const selector = rule.selector + + // 1) 移除 .\!xxx 类选择器(Tailwind important 修饰符,反斜杠转义的 ! 不兼容 WXSS) + const selectors = selector.split(',') + const hasEscapedImportant = selectors.some(s => /\.\\!/.test(s.trim())) + if (hasEscapedImportant) { + rule.remove() + return + } + + // 2) 移除 .space-[x|y]-* 规则(依赖 :not + ~ 兄弟组合器,WXSS 不兼容) + if (/\.space-[xy]-/.test(selector)) { + rule.remove() + return + } + + // 3) 移除 .divide-[x|y]-* 规则(同上,依赖 :not + ~) + if (/\.divide-[xy]-/.test(selector)) { + rule.remove() + return + } + } + } +} + +module.exports.postcss = true diff --git a/postcss.config.js b/postcss.config.js index 15b2d89..2ce9051 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,7 +1,12 @@ +const wxssIncompatiblePlugin = require('./postcss-remove-wxss-incompatible') + module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - 'postcss-nested': {} - } + plugins: [ + require('tailwindcss'), + require('autoprefixer'), + require('postcss-nested'), + // 移除 WXSS 不兼容的 Tailwind CSS 规则 + // 包括 .\!xxx(反斜杠转义 !)、space-x/y-*(:not + ~ 组合器)、divide-x/y-* 等 + wxssIncompatiblePlugin() + ] } diff --git a/src/components/QRScanModal.tsx b/src/components/QRScanModal.tsx index efbce60..c1e3106 100644 --- a/src/components/QRScanModal.tsx +++ b/src/components/QRScanModal.tsx @@ -233,7 +233,7 @@ const QRScanModal: React.FC = ({ )} {status === 'error' && ( - +