diff --git a/AGENTS.md b/AGENTS.md index 0ea9c29..dacf752 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,9 +8,9 @@ YGChatCS 是一个基于 uni-app + Vue 3 的多端应用,当前配置重点面 ## 技术栈 -- 框架:uni-app 3、Vue 3、Vite 5。 +- 框架:uni-app 3、Vue 3、Vite 5、Tailwind CSS 4。 - 状态管理:Pinia 3,使用 `pinia-plugin-unistorage` 做持久化。 -- 样式:SCSS,公共工具类在 `src/static/scss/`,全局变量在 `src/uni.scss`。 +- 样式:Tailwind CSS 4 通过 `weapp-tailwindcss` 适配微信小程序,负责页面和组件布局;SCSS 用于复杂视觉样式,公共样式在 `src/static/scss/`,全局变量在 `src/uni.scss`。 - 多端:保留 H5、App、各类小程序脚本;当前微信小程序配置最完整。 - 组件生态:`src/uni_modules/` 中包含 DCloud 插件和第三方插件,如 `uni-popup`、`uni-icons`、`z-paging`、`zero-markdown-view`。 @@ -34,7 +34,8 @@ yarn switch-client zhinian - `src/pages.json`:页面与分包路由。主页面是 `pages/index/index`,分包包括 `pages-order`、`pages-service`、`pages-quick`、`pages-booking`、`pages-bridge`。 - `src/manifest.json`:uni-app 多端配置;微信小程序 `appid`、隐私权限、插件配置在这里。 - `project.config.json`:微信开发者工具项目配置,根级 `appid` 需要与 `src/manifest.json` 保持一致。 -- `vite.config.js`:配置 `@` 指向 `src`,启用 `@dcloudio/vite-plugin-uni`,并对构建资源名做 md5/hash 处理。 +- `src/app.css`:Tailwind CSS 全局入口,配置源码扫描范围并排除构建产物、依赖和文档目录。 +- `vite.config.js`:配置 `@` 指向 `src`,启用 `@dcloudio/vite-plugin-uni`、Tailwind PostCSS 插件和 `weapp-tailwindcss` 小程序转换插件。 ## 目录地图 @@ -49,7 +50,7 @@ yarn switch-client zhinian - `src/pages-booking/`:预订页面。 - `src/pages-bridge/`:上传图片、保存图片等桥接页面。 - `src/pages/webview/`:内嵌 WebView 页面及桥接脚本,`src/router/index.js` 会把外部 URL 包装到这里。 -- `src/components/`:跨页面通用组件,如 `TopNavBar`、`Calender`、`ImageSwiper`、`TagsGroup`、`Stepper`、`CreateServiceOrder`、`Feedback` 等。 +- `src/components/`:跨页面通用组件,如 `TopNavBar`、`Calender`、`ImageSwiper`、`Stepper`、`CreateServiceOrder`、`Feedback` 等。 - `src/request/`:请求封装和 API 分组。 - `src/store/`:Pinia store,模块包括 `app`、`location`、`picture`、`selectedDate`。 - `src/constant/`:客户端配置、token key、事件常量、业务类型常量。 @@ -94,7 +95,9 @@ yarn switch-client ## 样式约定 - `.editorconfig` 要求 2 空格、LF、UTF-8、去尾随空格;Markdown 不强制去尾随空格且不强制最终换行。 -- 公共 SCSS 工具类集中在 `src/static/scss/index.scss` 及其拆分文件,很多页面依赖 `flex-*`、`w-*`、`h-*`、`px-*` 等类。 +- 后续新增或调整页面、组件时,所有新增或改动的布局样式统一使用 Tailwind CSS 工具类,包括 `flex/grid`、对齐、间距、尺寸、定位、溢出和响应式布局;不要再新增功能重复的 SCSS 布局类或内联布局样式。 +- Tailwind 类名应在模板中保持完整、可静态扫描,禁止通过字符串拼接动态生成类名;条件样式使用完整类名的对象或数组绑定。 +- SCSS 仅用于 Tailwind 不适合表达的复杂视觉效果、伪元素、动画和多端差异处理。现有公共 SCSS 工具类集中在 `src/static/scss/index.scss` 及其拆分文件,维护历史页面时可以继续复用,但不要扩展新的同类布局工具。 - 主题色变量在 `src/uni.scss`,会被 `switch-client` 自动改写。不要手工改一处忘记同步配置。 - 页面基本使用 `navigationStyle: "custom"`,导航栏通常由自定义组件实现。 diff --git a/src/components/Calender/README.md b/src/components/Calender/README.md deleted file mode 100644 index d341d7c..0000000 --- a/src/components/Calender/README.md +++ /dev/null @@ -1,548 +0,0 @@ -# 日历组件 (Calendar Component) - -## 功能需求分析 - -基于设计图片分析,该日历组件是一个酒店预订场景的低价日历弹窗,支持通过日期图标点击触发显示,需要实现以下细分功能: - -## 交互使用方式 - -### 基础用法 -通过点击日期图标打开日历组件: - -```vue - - - -``` - -### 演示文件 -- `year-demo.vue` - 全年日历演示(推荐) -- `demo.vue` - 完整的交互演示页面 -- `example.vue` - 详细的使用示例,包含单选和范围选择 - -### 跨年日历 -组件支持显示从当前月份到明年同月份的13个月日历,用户可以连续选择入住和离店日期: -1. 点击第一个日期设置入住日期 -2. 点击第二个日期设置离店日期 -3. 自动显示"入住"和"离店"标签 -4. 支持滚动浏览跨年日期范围 - -### 1. 弹窗容器结构 -#### 1.1 弹窗基础框架 -- [ ] 实现遮罩层背景(半透明黑色) -- [ ] 弹窗居中显示,支持垂直居中 -- [ ] 弹窗圆角设计(建议12px) -- [ ] 弹窗阴影效果 -- [ ] 弹窗动画效果(淡入淡出) - -#### 1.2 弹窗头部区域 -- [ ] 标题文字:"低价日历" -- [ ] 副标题文字:"以下价格为单晚参考价" -- [ ] 右上角关闭按钮(X图标) -- [ ] 关闭按钮点击交互 -- [ ] 头部区域背景色和分割线 - -### 2. 日历主体结构 -#### 2.1 周标题行 -- [ ] 显示周几标题:一、二、三、四、五、六、日 -- [ ] 周标题居中对齐 -- [ ] 周标题字体样式(灰色、小字号) - -#### 2.2 月份导航 -- [ ] 月份标题显示:"2024年5月"、"2024年6月" -- [ ] 月份标题居中显示 -- [ ] 月份标题字体加粗 -- [ ] 支持上下滑动切换月份(可选) - -### 3. 日期网格系统 -#### 3.1 日期格子基础 -- [ ] 7列网格布局(对应周一到周日) -- [ ] 每个格子固定宽高比 -- [ ] 格子间距设计 -- [ ] 格子圆角设计 - -#### 3.2 日期内容显示 -- [ ] 日期数字显示(居中对齐) -- [ ] 价格信息显示(¥449格式) -- [ ] 日期数字字体大小和颜色 -- [ ] 价格字体大小和颜色(较小、灰色) - -#### 3.3 日期状态管理 -- [ ] 普通可选日期(白色背景) -- [ ] 当前选中日期(蓝色背景,白色文字) -- [ ] 入住日期标记("入住"标签) -- [ ] 离店日期标记("离店"标签) -- [ ] 选择范围内日期(浅蓝色背景) -- [ ] 不可选日期(灰色背景,禁用状态) - -### 4. 交互功能实现 -#### 4.1 日期选择逻辑 -- [ ] 单击日期选择功能 -- [ ] 日期范围选择(入住-离店) -- [ ] 选择状态视觉反馈 -- [ ] 选择完成后的回调事件 - -#### 4.2 用户体验优化 -- [ ] 点击动画效果 -- [ ] 触摸反馈 -- [ ] 防止快速重复点击 -- [ ] 选择范围的视觉连接线(可选) - -### 5. 数据处理功能 -#### 5.1 价格数据管理 -- [ ] 价格数据结构设计 -- [ ] 价格数据绑定到日期 -- [ ] 价格格式化显示 -- [ ] 无价格数据的处理 - -#### 5.2 日期计算功能 -- [ ] 月份天数计算 -- [ ] 月份第一天星期几计算 -- [ ] 跨月份日期处理 -- [ ] 日期有效性验证 - -### 6. 响应式适配 -#### 6.1 移动端适配 -- [ ] 触摸屏操作优化 -- [ ] 不同屏幕尺寸适配 -- [ ] 横竖屏切换适配 -- [ ] 安全区域适配(刘海屏等) - -#### 6.2 字体和尺寸适配 -- [ ] 字体大小响应式调整 -- [ ] 格子尺寸响应式调整 -- [ ] 间距响应式调整 - -## 技术实现细节 - -### 组件接口设计 - -#### Props 属性 -```javascript -props: { - // 弹窗显示控制 - visible: { - type: Boolean, - default: false, - required: true - }, - - // 价格数据对象 - priceData: { - type: Object, - default: () => ({}), - // 格式: { '2024-05-17': 449, '2024-05-18': 399 } - }, - - // 默认选中日期 - defaultValue: { - type: [String, Array], - default: '', - // 单选: '2024-05-17' - // 范围选择: ['2024-05-17', '2024-05-19'] - }, - - // 选择模式 - mode: { - type: String, - default: 'single', - validator: (value) => ['single', 'range'].includes(value) - }, - - // 最小可选日期 - minDate: { - type: String, - default: () => new Date().toISOString().split('T')[0] - }, - - // 最大可选日期 - maxDate: { - type: String, - default: '' - }, - - // 禁用日期数组 - disabledDates: { - type: Array, - default: () => [] - }, - - // 自定义标签 - customLabels: { - type: Object, - default: () => ({}) - // 格式: { '2024-05-17': '入住', '2024-05-19': '离店' } - } -} -``` - -#### Events 事件 -```javascript -// 日期选择事件 -this.$emit('select', { - date: '2024-05-17', - price: 449, - mode: 'single' -}) - -// 范围选择事件 -this.$emit('range-select', { - startDate: '2024-05-17', - endDate: '2024-05-19', - startPrice: 449, - endPrice: 399, - totalDays: 2 -}) - -// 弹窗关闭事件 -this.$emit('close') - -// 月份切换事件 -this.$emit('month-change', { - year: 2024, - month: 5, - direction: 'next' // 'prev' | 'next' -}) - -// 日期点击事件(包含所有点击) -this.$emit('date-click', { - date: '2024-05-17', - price: 449, - disabled: false, - selected: true -}) -``` - -### 核心算法实现 - -#### 日期计算工具函数 -```javascript -// 获取月份天数 -getDaysInMonth(year, month) { - return new Date(year, month, 0).getDate() -} - -// 获取月份第一天是星期几 -getFirstDayOfMonth(year, month) { - return new Date(year, month - 1, 1).getDay() -} - -// 生成日期网格数据 -generateCalendarGrid(year, month) { - const daysInMonth = this.getDaysInMonth(year, month) - const firstDay = this.getFirstDayOfMonth(year, month) - const grid = [] - - // 填充空白格子 - for (let i = 0; i < firstDay; i++) { - grid.push(null) - } - - // 填充日期 - for (let day = 1; day <= daysInMonth; day++) { - const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}` - grid.push({ - date: dateStr, - day: day, - price: this.priceData[dateStr] || null, - disabled: this.isDateDisabled(dateStr), - selected: this.isDateSelected(dateStr), - inRange: this.isDateInRange(dateStr), - label: this.customLabels[dateStr] || '' - }) - } - - return grid -} -``` - -#### 选择状态管理 -```javascript -data() { - return { - selectedDates: [], - currentMonth: new Date().getMonth() + 1, - currentYear: new Date().getFullYear(), - isRangeSelecting: false, - rangeStart: null, - rangeEnd: null - } -}, - -methods: { - handleDateClick(dateInfo) { - if (dateInfo.disabled) return - - if (this.mode === 'single') { - this.selectedDates = [dateInfo.date] - this.$emit('select', dateInfo) - } else if (this.mode === 'range') { - this.handleRangeSelection(dateInfo) - } - }, - - handleRangeSelection(dateInfo) { - if (!this.rangeStart || (this.rangeStart && this.rangeEnd)) { - // 开始新的范围选择 - this.rangeStart = dateInfo.date - this.rangeEnd = null - this.isRangeSelecting = true - } else { - // 完成范围选择 - this.rangeEnd = dateInfo.date - this.isRangeSelecting = false - - // 确保开始日期小于结束日期 - if (new Date(this.rangeStart) > new Date(this.rangeEnd)) { - [this.rangeStart, this.rangeEnd] = [this.rangeEnd, this.rangeStart] - } - - this.$emit('range-select', { - startDate: this.rangeStart, - endDate: this.rangeEnd, - startPrice: this.priceData[this.rangeStart], - endPrice: this.priceData[this.rangeEnd], - totalDays: this.calculateDaysBetween(this.rangeStart, this.rangeEnd) - }) - } - } -} -``` - -### 样式设计规范 - -#### 颜色系统 -```scss -// 主色调 -$primary-color: #1890ff; -$primary-light: #e6f7ff; -$primary-dark: #0050b3; - -// 中性色 -$text-primary: #262626; -$text-secondary: #8c8c8c; -$text-disabled: #bfbfbf; -$background-white: #ffffff; -$background-gray: #f5f5f5; -$border-color: #d9d9d9; - -// 状态色 -$success-color: #52c41a; -$warning-color: #faad14; -$error-color: #ff4d4f; -``` - -#### 尺寸规范 -```scss -// 弹窗尺寸 -$modal-width: 350px; -$modal-max-height: 80vh; -$modal-border-radius: 12px; -$modal-padding: 20px; - -// 日期格子尺寸 -$date-cell-size: 44px; -$date-cell-gap: 2px; -$date-cell-border-radius: 6px; - -// 字体大小 -$font-size-title: 18px; -$font-size-subtitle: 14px; -$font-size-date: 16px; -$font-size-price: 12px; -$font-size-label: 10px; -``` - -## 开发实施计划 - -### 第一阶段:基础框架(1-2天) -- [ ] 创建组件基础结构 -- [ ] 实现弹窗容器和遮罩 -- [ ] 添加头部区域和关闭功能 -- [ ] 建立基础样式系统 - -### 第二阶段:日历核心(2-3天) -- [ ] 实现日期计算算法 -- [ ] 构建日期网格布局 -- [ ] 添加周标题和月份显示 -- [ ] 实现基础日期显示 - -### 第三阶段:交互功能(2-3天) -- [ ] 实现日期选择逻辑 -- [ ] 添加范围选择功能 -- [ ] 实现状态管理和视觉反馈 -- [ ] 添加价格数据绑定 - -### 第四阶段:优化完善(1-2天) -- [ ] 添加动画效果 -- [ ] 优化移动端体验 -- [ ] 完善边界情况处理 -- [ ] 性能优化和测试 - -## 使用示例 - -### 基础用法 -```vue - - - -``` - -### 高级用法 -```vue - - - -``` - -## 测试用例 - -### 单元测试 -- [ ] 日期计算函数测试 -- [ ] 选择逻辑测试 -- [ ] 价格数据绑定测试 -- [ ] 边界条件测试 - -### 集成测试 -- [ ] 用户交互流程测试 -- [ ] 不同设备适配测试 -- [ ] 性能压力测试 - -### 可访问性测试 -- [ ] 键盘导航测试 -- [ ] 屏幕阅读器兼容性 -- [ ] 色彩对比度检查 \ No newline at end of file diff --git a/src/components/Calender/demo.vue b/src/components/Calender/demo.vue deleted file mode 100644 index 809c4a5..0000000 --- a/src/components/Calender/demo.vue +++ /dev/null @@ -1,241 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/Calender/example.vue b/src/components/Calender/example.vue deleted file mode 100644 index 55eeb9d..0000000 --- a/src/components/Calender/example.vue +++ /dev/null @@ -1,315 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/Calender/images/日期-价格弹窗.png b/src/components/Calender/images/日期-价格弹窗.png deleted file mode 100644 index 543d484..0000000 Binary files a/src/components/Calender/images/日期-价格弹窗.png and /dev/null differ diff --git a/src/components/Calender/year-demo.vue b/src/components/Calender/year-demo.vue deleted file mode 100644 index ccdaf02..0000000 --- a/src/components/Calender/year-demo.vue +++ /dev/null @@ -1,269 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/CheckBox/propmt.md b/src/components/CheckBox/propmt.md deleted file mode 100644 index a865b92..0000000 --- a/src/components/CheckBox/propmt.md +++ /dev/null @@ -1,12 +0,0 @@ -## 复选框组件 - -## 提示词: - -使用 uniapp + vue3 组合式 api 开发微信小程序,要求如下: -1、按照提供的图片高度还原交互设计 -2、要求布局样式结构简洁明了,class 命名请按照模块名称来命名,例如:.checkbox-wrapper -3、可以使用 uniapp 内置的组件 - -## 备注 - -仅供学习、交流使用,请勿用于商业用途。 diff --git a/src/components/CommandWrapper/images/2025-07-14_144207.png b/src/components/CommandWrapper/images/2025-07-14_144207.png deleted file mode 100644 index b271e83..0000000 Binary files a/src/components/CommandWrapper/images/2025-07-14_144207.png and /dev/null differ diff --git a/src/components/CommandWrapper/propmt.md b/src/components/CommandWrapper/propmt.md deleted file mode 100644 index c14da46..0000000 --- a/src/components/CommandWrapper/propmt.md +++ /dev/null @@ -1,12 +0,0 @@ -## 消息体指令组件 - -## 提示词: - -使用 uniapp + vue3 组合式 api 开发微信小程序,要求如下: -1、按照提供的图片高度还原交互设计 -2、要求布局样式结构简洁明了,class 命名请按照模块名称来命名,例如:.command-wrapper -3、可以使用 uniapp 内置的组件 - -## 备注 - -仅供学习、交流使用,请勿用于商业用途。 diff --git a/src/components/CreateServiceOrder/images/2025-07-11_104138.png b/src/components/CreateServiceOrder/images/2025-07-11_104138.png deleted file mode 100644 index f71278c..0000000 Binary files a/src/components/CreateServiceOrder/images/2025-07-11_104138.png and /dev/null differ diff --git a/src/components/CreateServiceOrder/index.vue b/src/components/CreateServiceOrder/index.vue index 14d019b..ec2bc8e 100644 --- a/src/components/CreateServiceOrder/index.vue +++ b/src/components/CreateServiceOrder/index.vue @@ -1,84 +1,42 @@