diff --git a/.gitignore b/.gitignore index b8a25e7..38da8f3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ dist unpackage .hbuilderx .claude +docs \ No newline at end of file diff --git a/.superpowers/brainstorm/14136-1778668898.44814/state/server.pid b/.superpowers/brainstorm/14136-1778668898.44814/state/server.pid new file mode 100644 index 0000000..afae555 --- /dev/null +++ b/.superpowers/brainstorm/14136-1778668898.44814/state/server.pid @@ -0,0 +1 @@ +15336 diff --git a/.superpowers/brainstorm/2672-1778668863.69592/state/server.pid b/.superpowers/brainstorm/2672-1778668863.69592/state/server.pid new file mode 100644 index 0000000..e69de29 diff --git a/.superpowers/brainstorm/30768-1778668817.27797/state/server.err b/.superpowers/brainstorm/30768-1778668817.27797/state/server.err new file mode 100644 index 0000000..e69de29 diff --git a/.superpowers/brainstorm/30768-1778668817.27797/state/server.pid b/.superpowers/brainstorm/30768-1778668817.27797/state/server.pid new file mode 100644 index 0000000..e69de29 diff --git a/.superpowers/brainstorm/3476-1778668926.99711/content/component-scope-approach.html b/.superpowers/brainstorm/3476-1778668926.99711/content/component-scope-approach.html new file mode 100644 index 0000000..7bf3577 --- /dev/null +++ b/.superpowers/brainstorm/3476-1778668926.99711/content/component-scope-approach.html @@ -0,0 +1,53 @@ +

ChatModule 组件还原范围确认

+

我已扫描 14 个 HTML 视觉稿。下面按实现视角分组:相同视觉结构会抽共享基础卡片/媒体/详情页容器,组件只还原 之间的内容。

+ +
+
Detected component families
+
+
+
+

内容/详情卡

+

C0 长文本卡、C0+ 组合卡、C13 公告卡:列表态 + 详情态,复用详情页头部、返回、富文本正文、行动区。

+
+
+
+
+

POI / 列表 / 路线

+

C1 POI 详情、C2 列表、C2 多 POI、C3 对比、C4 路线、C5 设施位置:复用卡片壳、标签、图片缩略图、信息行。

+
+
+
+
+

媒体 / 操作卡

+

C7 大图、C8 地图导航、C10 AIGC 合照、C12 FAQ:复用媒体卡壳、底部说明、主按钮/入口行。

+
+
+
+
+ +
+
Recommended implementation direction
+
+
+
A
+
+

Props-first 组件库(推荐)

+

每个新 ChatModule 组件只接收 props,不在组件内拉接口;示例数据放到独立 mock 文件或父级传入,避免硬编码。

+
+
+
+
B
+
+

容器组件 + 展示组件

+

每个视觉组件拆成容器和纯展示两层;适合马上接真实接口,但文件数量和接线工作更多。

+
+
+
+
C
+
+

静态视觉还原优先

+

先按 HTML 固定数据还原,再二次抽数据;最快看见 UI,但违反“mock 数据不要硬编码”的风险最高。

+
+
+
+
diff --git a/.superpowers/brainstorm/3476-1778668926.99711/state/server-info b/.superpowers/brainstorm/3476-1778668926.99711/state/server-info new file mode 100644 index 0000000..66c49e0 --- /dev/null +++ b/.superpowers/brainstorm/3476-1778668926.99711/state/server-info @@ -0,0 +1 @@ +{"type":"server-started","port":63006,"host":"127.0.0.1","url_host":"localhost","url":"http://localhost:63006","screen_dir":"E:\\zn\\YGChatCS\\.superpowers\\brainstorm\\3476-1778668926.99711\\content","state_dir":"E:\\zn\\YGChatCS\\.superpowers\\brainstorm\\3476-1778668926.99711\\state"} diff --git a/.superpowers/brainstorm/43412-1778668874.64192/state/server.pid b/.superpowers/brainstorm/43412-1778668874.64192/state/server.pid new file mode 100644 index 0000000..9f35f8e --- /dev/null +++ b/.superpowers/brainstorm/43412-1778668874.64192/state/server.pid @@ -0,0 +1 @@ +10800 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..448d288 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,136 @@ +# YGChatCS 项目速览 + +本文档面向接手本仓库的 AI 编程助手。开始改代码前请先读这里,再按需深入具体文件。 + +## 项目定位 + +YGChatCS 是一个基于 uni-app + Vue 3 的多端应用,当前配置重点面向微信小程序。业务上以酒店/文旅场景的 AI 聊天助手为主,包含首页聊天、发现内容、商品/房型详情、订单、工单服务、快捷预订、WebView 桥接等模块。 + +## 技术栈 + +- 框架:uni-app 3、Vue 3、Vite 5。 +- 状态管理:Pinia 3,使用 `pinia-plugin-unistorage` 做持久化。 +- 样式:SCSS,公共工具类在 `src/static/scss/`,全局变量在 `src/uni.scss`。 +- 多端:保留 H5、App、各类小程序脚本;当前微信小程序配置最完整。 +- 组件生态:`src/uni_modules/` 中包含 DCloud 插件和第三方插件,如 `uni-popup`、`uni-icons`、`z-paging`、`zero-markdown-view`。 + +## 常用命令 + +包管理器字段声明为 Yarn 1: + +```bash +yarn install +yarn dev:mp-weixin +yarn build:mp-weixin +yarn dev:h5 +yarn build:h5 +yarn switch-client zhinian +``` + +`package-lock.json` 和 `yarn.lock` 同时存在。除非任务明确要求,不要随意重生成或混改锁文件;优先遵循 `package.json` 的 `packageManager`。 + +## 关键入口 + +- `src/main.js`:创建 Vue/uni-app 应用,注册 Pinia;微信小程序环境注册 `utils/share`。 +- `src/App.vue`:应用生命周期入口,`onLaunch` 会调用 `getEvnUrl()` 获取/设置服务地址,并调用 `refreshToken()` 刷新登录态。 +- `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/pages/`:主包页面和聊天相关组件。`pages/index/index.vue` 是首页壳,组合聊天主列表、日历、更多服务和抽屉。 +- `src/pages/ChatMain/`:聊天主体验,包括顶部导航、欢迎区、输入区、消息卡片、长回答页、通知消息等。 +- `src/pages/ChatModule/`:AI 工具调用渲染模块,例如快捷预订、发现卡片、地图、活动、推荐内容、长答案、图片/商品卡等。 +- `src/pages/Discovery/`:发现页内容流和快捷问题。 +- `src/pages/goods/`:商品/房型详情、相册、套餐、设施、日期选择和确认组件。 +- `src/pages-order/`:订单列表、订单详情及订单卡片、二维码、状态、用户信息等组件。 +- `src/pages-service/`:服务/工单订单列表。 +- `src/pages-quick/`:快捷入口列表及卡片。 +- `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/request/`:请求封装和 API 分组。 +- `src/store/`:Pinia store,模块包括 `app`、`location`、`picture`、`selectedDate`。 +- `src/constant/`:客户端配置、token key、事件常量、业务类型常量。 +- `src/utils/`:WebSocket、流式/打字机、URL 参数、分享、更新等工具。 +- `scripts/`:客户配置切换脚本。 + +## 请求、环境与登录 + +- `src/request/base/request.js` 是统一请求封装。相对 URL 会拼接 `useAppStore().serverConfig.baseUrl`,请求头会带 `clientId`、token 和位置信息。 +- `src/request/base/baseUrl.js` 定义生产/测试 HTTP 和 WSS 地址。 +- `src/request/base/config.js` 控制环境地址。`developVersion = true` 时直接使用测试地址;发布前需关注 `versionValue` 和 `developVersion`。 +- `src/request/api/` 按业务拆分 API:登录、主页面数据、会话、商品、订单、工单、反馈、服务地址、文件上传、AI 流式接口等。 +- 登录与 token 逻辑在 `src/hooks/useGoLogin.js`、`src/manager/LoginManager.js`、`src/constant/token.js`。token key 会按当前客户端类型隔离。 +- HTTP 返回 `424` 时请求层会移除 token、发出登出事件,并跳转登录。 + +## AI 聊天与实时通信 + +- 主聊天列表在 `src/pages/ChatMain/ChatMainList/index.vue`,文件较大,是聊天状态、消息渲染、WebSocket 初始化和发送的核心。 +- `src/utils/WebSocketManager.js` 是跨端 WebSocket 管理器,负责连接、重连、队列、发送和销毁。 +- `src/request/api/AgentChatStream.js` 是微信小程序端的分块/流式请求封装,使用 `uni.request({ enableChunked: true })` 解析 SSE 风格数据;也提供 `stopAbortTask()` 终止当前请求。 +- AI 返回的 `toolCall.componentName` 会在聊天列表中映射到 `ChatModule` 或通用组件。新增工具卡片时,通常需要同时改组件、渲染分支和数据结构处理。 + +## 多客户端配置 + +根目录 `client-configs.json` 保存多客户端配置:`zhinian`、`nianhelper`、`duohua`、`tianmu`。当前 `src/constant/base.js` 的 `getCurrentConfig()` 返回 `CLIENT_CONFIGS.zhinian`。 + +切换客户配置请使用: + +```bash +yarn switch-client +``` + +脚本 `scripts/update-appid.js` 会更新: + +- `src/constant/base.js` 的当前客户端。 +- `src/manifest.json` 的 `mp-weixin.appid`。 +- `project.config.json` 的根级 `appid`。 +- `src/uni.scss` 的主题色变量。 + +改配置时要保证这些文件同步,尤其是微信小程序 appid 与主题色。 + +## 样式约定 + +- `.editorconfig` 要求 2 空格、LF、UTF-8、去尾随空格;Markdown 不强制去尾随空格且不强制最终换行。 +- 公共 SCSS 工具类集中在 `src/static/scss/index.scss` 及其拆分文件,很多页面依赖 `flex-*`、`w-*`、`h-*`、`px-*` 等类。 +- 主题色变量在 `src/uni.scss`,会被 `switch-client` 自动改写。不要手工改一处忘记同步配置。 +- 页面基本使用 `navigationStyle: "custom"`,导航栏通常由自定义组件实现。 + +## 编码与文本注意事项 + +当前终端读取部分中文注释、README 和字符串时显示为乱码,但项目文件声明为 UTF-8。修改这些文件时: + +- 不要因为显示乱码就大面积重写注释或中文文案。 +- 尽量只改任务相关代码块。 +- 涉及中文展示文案时,在编辑器中确认真实编码和页面效果。 + +## 开发注意事项 + +- 优先使用 `@/` 别名引入 `src` 下模块。 +- 不要直接改 `dist/`,它是构建产物。 +- 不要随意改 `src/uni_modules/` 中第三方插件源码,除非任务就是修补插件行为。 +- 新增页面必须同步 `src/pages.json`;新增分包页面要放入对应 `subPackages`。 +- 需要持久化的全局状态优先放在 Pinia store,并按现有模块风格使用 `unistorage: true`。 +- 网络请求优先新增到 `src/request/api/`,复用 `src/request/base/request.js`,不要在页面里散落裸 `uni.request`,流式/分块场景除外。 +- 跳转外部 H5 优先使用 `src/router/index.js` 的 WebView 包装方式。 +- 需要登录态的交互参考 `checkToken()`、`goLogin()` 和现有事件常量。 + +## 验证建议 + +仓库当前没有明确的测试脚本。完成修改后至少做对应平台构建或运行: + +```bash +yarn build:mp-weixin +``` + +如果只改 H5 可补充: + +```bash +yarn build:h5 +``` + +涉及客户切换时,运行 `yarn switch-client ` 后检查 `src/manifest.json`、`project.config.json`、`src/constant/base.js`、`src/uni.scss` 的同步变化。 diff --git a/src/pages.json b/src/pages.json index 359998d..54d45b4 100644 --- a/src/pages.json +++ b/src/pages.json @@ -1,16 +1,16 @@ { "pages": [ - { - "path": "pages/index/index", - "style": { - "navigationStyle": "custom", - "disableScroll": true, - "app-plus": { - "bounce": "none", - "scrollIndicator": "none" - } - } - }, + { + "path": "pages/index/index", + "style": { + "navigationStyle": "custom", + "disableScroll": true, + "app-plus": { + "bounce": "none", + "scrollIndicator": "none" + } + } + }, { "path": "pages/login/index", "style": { @@ -49,6 +49,12 @@ "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/test/index", + "style": { + "navigationStyle": "custom" + } } ], "subPackages": [ @@ -127,4 +133,4 @@ "backgroundColor": "#F8F8F8" }, "uniIdRouter": {} -} +} diff --git a/src/pages/ChatModule/AigcPhotoCard/index.vue b/src/pages/ChatModule/AigcPhotoCard/index.vue new file mode 100644 index 0000000..fa49b33 --- /dev/null +++ b/src/pages/ChatModule/AigcPhotoCard/index.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/src/pages/ChatModule/AigcPhotoCard/mocks.js b/src/pages/ChatModule/AigcPhotoCard/mocks.js new file mode 100644 index 0000000..92bc76c --- /dev/null +++ b/src/pages/ChatModule/AigcPhotoCard/mocks.js @@ -0,0 +1,11 @@ +export default { + icon: "AI", + title: "生成一张景区合照", + subtitle: "上传照片后生成同框纪念照", + buttonText: "开始生成", + images: [ + "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80", + "https://images.unsplash.com/photo-1529156069898-49953e39b3ac?auto=format&fit=crop&w=400&q=80", + "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?auto=format&fit=crop&w=400&q=80", + ], +}; diff --git a/src/pages/ChatModule/AigcPhotoCard/styles/index.scss b/src/pages/ChatModule/AigcPhotoCard/styles/index.scss new file mode 100644 index 0000000..aa2dade --- /dev/null +++ b/src/pages/ChatModule/AigcPhotoCard/styles/index.scss @@ -0,0 +1,35 @@ +.aigc-photo-card { + background: linear-gradient(145deg, #ffffff 0%, #f0fdfa 100%); +} + +.aigc-photo-card__body { +} + +.aigc-photo-card__icon { + color: #0f766e; +} + +.aigc-photo-card__content { + min-width: 0; +} + +.aigc-photo-card__title { + color: #134e4a; +} + +.aigc-photo-card__subtitle { + margin-top: 5px; +} + +.aigc-photo-card__preview { +} + +.aigc-photo-card__image { +} + +.aigc-photo-card__button { +} + +.aigc-photo-card__button.is-disabled { + opacity: 0.55; +} diff --git a/src/pages/ChatModule/FacilityLocationCard/index.vue b/src/pages/ChatModule/FacilityLocationCard/index.vue new file mode 100644 index 0000000..d9b0a00 --- /dev/null +++ b/src/pages/ChatModule/FacilityLocationCard/index.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/pages/ChatModule/FacilityLocationCard/mocks.js b/src/pages/ChatModule/FacilityLocationCard/mocks.js new file mode 100644 index 0000000..44cbdf6 --- /dev/null +++ b/src/pages/ChatModule/FacilityLocationCard/mocks.js @@ -0,0 +1,11 @@ +export default { + title: "附近设施位置", + badge: "设施引导", + cover: "https://images.unsplash.com/photo-1518005020951-eccb494ad742?auto=format&fit=crop&w=900&q=80", + description: "根据你当前位置推荐最近的服务点和补给点。", + facilities: [ + { id: "f1", name: "游客中心", meta: "咨询、补给、卫生间", distance: "120m" }, + { id: "f2", name: "观光车站", meta: "前往水上森林", distance: "260m" }, + { id: "f3", name: "咖啡轻食", meta: "可短暂停留", distance: "360m" }, + ], +}; diff --git a/src/pages/ChatModule/FacilityLocationCard/styles/index.scss b/src/pages/ChatModule/FacilityLocationCard/styles/index.scss new file mode 100644 index 0000000..a6a438c --- /dev/null +++ b/src/pages/ChatModule/FacilityLocationCard/styles/index.scss @@ -0,0 +1,58 @@ +.facility-location-card__hero { + position: relative; + padding: 8px; +} + +.facility-location-card__image { +} + +.facility-location-card__overlay { + position: absolute; + left: 20px; + right: 20px; + bottom: 20px; +} + +.facility-location-card__title { + margin-top: 8px; + color: #fff; + font-size: 18px; + font-weight: 900; + text-shadow: 0 2px 8px rgba(0, 0, 0, 0.24); +} + +.facility-location-card__body { + padding-top: 6px; +} + +.facility-location-card__desc { + line-height: 20px; +} + +.facility-location-card__list { + margin-top: 14px; +} + +.facility-location-card__item { + padding: 11px 0; +} + +.facility-location-card__dot { + width: 8px; + height: 8px; + background: #06b6d4; +} + +.facility-location-card__info { + min-width: 0; +} + +.facility-location-card__name { +} + +.facility-location-card__meta { + margin-top: 3px; +} + +.facility-location-card__distance { +} diff --git a/src/pages/ChatModule/FaqHelpCard/index.vue b/src/pages/ChatModule/FaqHelpCard/index.vue new file mode 100644 index 0000000..6adbbde --- /dev/null +++ b/src/pages/ChatModule/FaqHelpCard/index.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/pages/ChatModule/FaqHelpCard/mocks.js b/src/pages/ChatModule/FaqHelpCard/mocks.js new file mode 100644 index 0000000..e2778b7 --- /dev/null +++ b/src/pages/ChatModule/FaqHelpCard/mocks.js @@ -0,0 +1,10 @@ +export default { + title: "常见问题", + subtitle: "快速了解游览和服务信息", + badge: "FAQ", + questions: [ + { id: "q1", question: "景区几点停止入园?", answer: "通常闭园前 1 小时停止入园,节假日以现场公告为准。" }, + { id: "q2", question: "可以携带宠物吗?", answer: "多数室内区域不支持宠物进入,导盲犬等服务犬除外。" }, + { id: "q3", question: "下雨还能游玩吗?", answer: "小雨可游览,雨后水景更好,但请注意栈道湿滑。" }, + ], +}; diff --git a/src/pages/ChatModule/FaqHelpCard/styles/index.scss b/src/pages/ChatModule/FaqHelpCard/styles/index.scss new file mode 100644 index 0000000..f60d7be --- /dev/null +++ b/src/pages/ChatModule/FaqHelpCard/styles/index.scss @@ -0,0 +1,36 @@ +.faq-help-card { +} + +.faq-help-card__header { + margin-bottom: 12px; +} + +.faq-help-card__title { +} + +.faq-help-card__subtitle { + margin-top: 4px; +} + +.faq-help-card__list { +} + +.faq-help-card__item { +} + +.faq-help-card__item.is-open { + background: #eff6ff; +} + +.faq-help-card__question { +} + +.faq-help-card__arrow { + font-size: 18px; + line-height: 14px; +} + +.faq-help-card__answer { + margin-top: 8px; + line-height: 20px; +} diff --git a/src/pages/ChatModule/LongTextGuideCard/index.vue b/src/pages/ChatModule/LongTextGuideCard/index.vue new file mode 100644 index 0000000..dbbbb6d --- /dev/null +++ b/src/pages/ChatModule/LongTextGuideCard/index.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/pages/ChatModule/LongTextGuideCard/mocks.js b/src/pages/ChatModule/LongTextGuideCard/mocks.js new file mode 100644 index 0000000..2ca5ec1 --- /dev/null +++ b/src/pages/ChatModule/LongTextGuideCard/mocks.js @@ -0,0 +1,17 @@ +export default { + cards: [ + { + id: "guide-waterfall", + badge: "攻略", + time: "约 3 分钟阅读", + title: "瀑布观景路线怎么走更顺", + summary: "从入口到核心观景台的轻量攻略,适合第一次到访时快速决策。", + footer: "查看完整攻略", + sections: [ + { title: "推荐顺序", content: "先到主观景台确认水量,再沿木栈道前往侧面机位,回程避开逆光时段。" }, + { title: "体验提醒", content: "雨后地面湿滑,建议预留 40 分钟,不要在低洼处长时间停留。" }, + ], + action: { title: "查看景点详情", subtitle: "开放时间、距离与导航", icon: "i" }, + }, + ], +}; diff --git a/src/pages/ChatModule/LongTextGuideCard/styles/index.scss b/src/pages/ChatModule/LongTextGuideCard/styles/index.scss new file mode 100644 index 0000000..3e1dc88 --- /dev/null +++ b/src/pages/ChatModule/LongTextGuideCard/styles/index.scss @@ -0,0 +1,58 @@ +.long-text-guide-card, +.long-text-guide-card__list { +} + +.long-text-guide-card__item { + margin-bottom: 12px; +} + +.long-text-guide-card__body { +} + +.long-text-guide-card__meta { + margin-bottom: 10px; +} + +.long-text-guide-card__time { + color: #94a3b8; + font-size: 11px; + font-weight: 700; +} + +.long-text-guide-card__title { + line-height: 20px; +} + +.long-text-guide-card__summary { + margin-top: 8px; + line-height: 19px; +} + +.long-text-guide-card__footer { +} + +.long-text-guide-card__arrow { + font-size: 22px; +} + +.long-text-guide-card__detail { +} + +.long-text-guide-card__section { + margin-bottom: 16px; +} + +.long-text-guide-card__section-title { + margin-bottom: 8px; +} + +.long-text-guide-card__section-text { + line-height: 22px; +} + +.long-text-guide-card__action { + margin-top: 18px; + padding: 8px; + border-radius: 20px; + background: #fffbeb; +} diff --git a/src/pages/ChatModule/LongTextGuideComboCard/index.vue b/src/pages/ChatModule/LongTextGuideComboCard/index.vue new file mode 100644 index 0000000..81599ef --- /dev/null +++ b/src/pages/ChatModule/LongTextGuideComboCard/index.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/src/pages/ChatModule/LongTextGuideComboCard/mocks.js b/src/pages/ChatModule/LongTextGuideComboCard/mocks.js new file mode 100644 index 0000000..bf93d5f --- /dev/null +++ b/src/pages/ChatModule/LongTextGuideComboCard/mocks.js @@ -0,0 +1,22 @@ +export default { + cards: [ + { + id: "combo-guide", + badge: "组合攻略", + time: "约 5 分钟阅读", + title: "一天内拍照、游览和用餐怎么安排", + summary: "把景点详情、大图机位、导航和票务入口组合到同一张攻略卡后续行动区。", + footer: "展开攻略和行动", + sections: [ + { title: "上午", content: "先拍远景与人像,再进入主步道游览。" }, + { title: "下午", content: "根据光线选择二号机位,最后去游客中心附近补给。" }, + ], + action: { title: "查看景点详情", subtitle: "开放时间与路线", icon: "i" }, + }, + ], + actions: [ + { title: "查看机位图", subtitle: "高清大图与拍摄角度", icon: "▣", tone: "blue" }, + { title: "带我去这里", subtitle: "地图路线与步行距离", icon: "⌖", tone: "green" }, + { title: "相关票务", subtitle: "门票和套票入口", icon: "¥", tone: "amber" }, + ], +}; diff --git a/src/pages/ChatModule/LongTextGuideComboCard/styles/index.scss b/src/pages/ChatModule/LongTextGuideComboCard/styles/index.scss new file mode 100644 index 0000000..262ab28 --- /dev/null +++ b/src/pages/ChatModule/LongTextGuideComboCard/styles/index.scss @@ -0,0 +1,8 @@ +.long-text-guide-combo-card { + width: 100%; +} + +.long-text-guide-combo-card__actions { + background: rgba(255, 255, 255, 0.62); + box-shadow: 0 8px 26px rgba(15, 23, 42, 0.04); +} diff --git a/src/pages/ChatModule/MapNavigationCard/index.vue b/src/pages/ChatModule/MapNavigationCard/index.vue new file mode 100644 index 0000000..3b4ebf1 --- /dev/null +++ b/src/pages/ChatModule/MapNavigationCard/index.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/pages/ChatModule/MapNavigationCard/mocks.js b/src/pages/ChatModule/MapNavigationCard/mocks.js new file mode 100644 index 0000000..c9785cf --- /dev/null +++ b/src/pages/ChatModule/MapNavigationCard/mocks.js @@ -0,0 +1,7 @@ +export default { + mapImage: "https://images.unsplash.com/photo-1524661135-423995f22d0b?auto=format&fit=crop&w=900&q=80", + pinText: "目的地", + title: "前往翠谷瀑布", + distance: "距你 500m · 步行约 8 分钟", + buttonText: "导航", +}; diff --git a/src/pages/ChatModule/MapNavigationCard/styles/index.scss b/src/pages/ChatModule/MapNavigationCard/styles/index.scss new file mode 100644 index 0000000..f8a3592 --- /dev/null +++ b/src/pages/ChatModule/MapNavigationCard/styles/index.scss @@ -0,0 +1,39 @@ +.map-navigation-card__map { + position: relative; + padding: 8px; +} + +.map-navigation-card__image { +} + +.map-navigation-card__pin { + position: absolute; + top: 18px; + left: 18px; + padding: 5px 9px; + border-radius: 999px; + background: rgba(255, 255, 255, 0.9); +} + +.map-navigation-card__bar { + padding: 0 14px 14px; +} + +.map-navigation-card__info { + min-width: 0; +} + +.map-navigation-card__title { +} + +.map-navigation-card__distance { + margin-top: 4px; +} + +.map-navigation-card__button { + padding: 9px 14px; +} + +.map-navigation-card__button.is-disabled { + opacity: 0.55; +} diff --git a/src/pages/ChatModule/MultiPoiRecommendationCard/index.vue b/src/pages/ChatModule/MultiPoiRecommendationCard/index.vue new file mode 100644 index 0000000..2ea762f --- /dev/null +++ b/src/pages/ChatModule/MultiPoiRecommendationCard/index.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/src/pages/ChatModule/MultiPoiRecommendationCard/mocks.js b/src/pages/ChatModule/MultiPoiRecommendationCard/mocks.js new file mode 100644 index 0000000..d96845d --- /dev/null +++ b/src/pages/ChatModule/MultiPoiRecommendationCard/mocks.js @@ -0,0 +1,34 @@ +export default { + items: [ + { + id: "poi-1", + title: "翠谷瀑布", + category: "自然景观", + cover: "https://images.unsplash.com/photo-1432405972618-c60b0225b8f9?auto=format&fit=crop&w=900&q=80", + description: "主线步道上的核心停留点,适合拍摄水景。", + facts: [ + { label: "距离", value: "500m" }, + { label: "推荐", value: "高" }, + { label: "耗时", value: "30m" }, + ], + tags: ["亲水", "拍照"], + actionTitle: "导航到瀑布", + actionSubtitle: "步行约 8 分钟", + }, + { + id: "poi-2", + title: "水上森林", + category: "亲子友好", + cover: "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=900&q=80", + description: "树影和水面交错,适合慢游和家庭出行。", + facts: [ + { label: "距离", value: "1.2km" }, + { label: "推荐", value: "中高" }, + { label: "耗时", value: "45m" }, + ], + tags: ["轻徒步", "观景"], + actionTitle: "导航到水上森林", + actionSubtitle: "观光车约 6 分钟", + }, + ], +}; diff --git a/src/pages/ChatModule/MultiPoiRecommendationCard/styles/index.scss b/src/pages/ChatModule/MultiPoiRecommendationCard/styles/index.scss new file mode 100644 index 0000000..5f41bba --- /dev/null +++ b/src/pages/ChatModule/MultiPoiRecommendationCard/styles/index.scss @@ -0,0 +1,10 @@ +.multi-poi-recommendation-card { + display: flex; + flex-direction: column; + gap: 12px; + width: 100%; +} + +.multi-poi-recommendation-card__item { + flex-shrink: 0; +} diff --git a/src/pages/ChatModule/NoticeCard/index.vue b/src/pages/ChatModule/NoticeCard/index.vue new file mode 100644 index 0000000..ff1c7d3 --- /dev/null +++ b/src/pages/ChatModule/NoticeCard/index.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/src/pages/ChatModule/NoticeCard/mocks.js b/src/pages/ChatModule/NoticeCard/mocks.js new file mode 100644 index 0000000..a01e994 --- /dev/null +++ b/src/pages/ChatModule/NoticeCard/mocks.js @@ -0,0 +1,24 @@ +export default { + title: "景区公告", + subtitle: "重要通知与运营提醒", + badge: "公告", + notices: [ + { + id: "notice-1", + title: "观光车运营时间调整", + summary: "因道路维护,今日 16:30 后部分站点临时调整。", + date: "今日", + type: "运营", + cover: "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=900&q=80", + paragraphs: ["今日 16:30 后,水上森林站点将临时调整至游客中心东侧。", "已购票游客可凭原票乘坐接驳车,请根据现场指引有序排队。"], + }, + { + id: "notice-2", + title: "雨后栈道防滑提醒", + summary: "部分亲水路段地面湿滑,请穿防滑鞋并照看儿童。", + date: "昨天", + type: "安全", + paragraphs: ["雨后栈道区域湿滑,请勿奔跑或翻越护栏。", "如遇临时封闭,请服从现场工作人员安排。"], + }, + ], +}; diff --git a/src/pages/ChatModule/NoticeCard/styles/index.scss b/src/pages/ChatModule/NoticeCard/styles/index.scss new file mode 100644 index 0000000..ed8f326 --- /dev/null +++ b/src/pages/ChatModule/NoticeCard/styles/index.scss @@ -0,0 +1,60 @@ +.notice-card { + width: 100%; +} + +.notice-card__list { +} + +.notice-card__header { + margin-bottom: 12px; +} + +.notice-card__title { +} + +.notice-card__subtitle { + margin-top: 4px; +} + +.notice-card__item { + padding: 13px 0; +} + +.notice-card__item:last-child { + border-bottom: none; +} + +.notice-card__item.is-disabled { + opacity: 0.55; +} + +.notice-card__item-body { + min-width: 0; +} + +.notice-card__item-title { +} + +.notice-card__item-desc { + margin-top: 5px; + line-height: 17px; +} + +.notice-card__item-date { +} + +.notice-card__detail { +} + +.notice-card__cover { + margin-bottom: 14px; +} + +.notice-card__meta { + margin-bottom: 12px; +} + +.notice-card__paragraph { + margin-bottom: 12px; + line-height: 22px; +} diff --git a/src/pages/ChatModule/PoiCompareCard/index.vue b/src/pages/ChatModule/PoiCompareCard/index.vue new file mode 100644 index 0000000..738cb66 --- /dev/null +++ b/src/pages/ChatModule/PoiCompareCard/index.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/src/pages/ChatModule/PoiCompareCard/mocks.js b/src/pages/ChatModule/PoiCompareCard/mocks.js new file mode 100644 index 0000000..228b0d2 --- /dev/null +++ b/src/pages/ChatModule/PoiCompareCard/mocks.js @@ -0,0 +1,29 @@ +export default { + title: "两个目的地怎么选", + subtitle: "按距离、拍照和亲子友好度对比", + badge: "对比", + items: [ + { + id: "compare-1", + title: "翠谷瀑布", + score: "更适合拍照", + cover: "https://images.unsplash.com/photo-1432405972618-c60b0225b8f9?auto=format&fit=crop&w=800&q=80", + details: [ + { label: "优势", value: "景观集中、出片快" }, + { label: "距离", value: "约 500m" }, + { label: "建议", value: "上午优先前往" }, + ], + }, + { + id: "compare-2", + title: "水上森林", + score: "更适合慢游", + cover: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?auto=format&fit=crop&w=800&q=80", + details: [ + { label: "优势", value: "路线平缓、停留舒服" }, + { label: "距离", value: "约 1.2km" }, + { label: "建议", value: "下午光线更柔和" }, + ], + }, + ], +}; diff --git a/src/pages/ChatModule/PoiCompareCard/styles/index.scss b/src/pages/ChatModule/PoiCompareCard/styles/index.scss new file mode 100644 index 0000000..6b9efb9 --- /dev/null +++ b/src/pages/ChatModule/PoiCompareCard/styles/index.scss @@ -0,0 +1,56 @@ +.poi-compare-card { + width: 100%; +} + +.poi-compare-card__overview { +} + +.poi-compare-card__header { + margin-bottom: 14px; +} + +.poi-compare-card__title { +} + +.poi-compare-card__subtitle { + margin-top: 4px; +} + +.poi-compare-card__grid { +} + +.poi-compare-card__option { +} + +.poi-compare-card__option:active { + opacity: 0.86; +} + +.poi-compare-card__option.is-disabled { + opacity: 0.55; +} + +.poi-compare-card__image { + margin-bottom: 8px; +} + +.poi-compare-card__option-title { +} + +.poi-compare-card__score { + margin-top: 4px; +} + +.poi-compare-card__detail { +} + +.poi-compare-card__row { + padding: 12px 0; +} + +.poi-compare-card__row-label { +} + +.poi-compare-card__row-value { + text-align: right; +} diff --git a/src/pages/ChatModule/PoiDetailCard/index.vue b/src/pages/ChatModule/PoiDetailCard/index.vue new file mode 100644 index 0000000..b9f223a --- /dev/null +++ b/src/pages/ChatModule/PoiDetailCard/index.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/src/pages/ChatModule/PoiDetailCard/mocks.js b/src/pages/ChatModule/PoiDetailCard/mocks.js new file mode 100644 index 0000000..01010d8 --- /dev/null +++ b/src/pages/ChatModule/PoiDetailCard/mocks.js @@ -0,0 +1,14 @@ +export default { + title: "翠谷瀑布观景台", + category: "必看 POI", + cover: "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?auto=format&fit=crop&w=900&q=80", + description: "靠近主步道的核心观景点,适合拍摄瀑布全景,也适合短暂停留休息。", + facts: [ + { label: "步行", value: "8 分钟" }, + { label: "热度", value: "4.8" }, + { label: "停留", value: "30 分钟" }, + ], + tags: ["亲子友好", "拍照", "近游客中心"], + actionTitle: "打开导航地图", + actionSubtitle: "查看路线与距离", +}; diff --git a/src/pages/ChatModule/PoiDetailCard/styles/index.scss b/src/pages/ChatModule/PoiDetailCard/styles/index.scss new file mode 100644 index 0000000..7d09643 --- /dev/null +++ b/src/pages/ChatModule/PoiDetailCard/styles/index.scss @@ -0,0 +1,48 @@ +.poi-detail-card { + position: relative; +} + +.poi-detail-card__hero { + position: relative; + padding: 8px 8px 0; +} + +.poi-detail-card__media { +} + +.poi-detail-card__tag { + position: absolute; + left: 18px; + bottom: 10px; +} + +.poi-detail-card__body { +} + +.poi-detail-card__title { + line-height: 24px; +} + +.poi-detail-card__desc { + margin-top: 8px; + line-height: 20px; +} + +.poi-detail-card__facts { +} + +.poi-detail-card__fact { +} + +.poi-detail-card__fact-value { +} + +.poi-detail-card__fact-label { + margin-top: 3px; +} + +.poi-detail-card__chips { +} + +.poi-detail-card__action { +} diff --git a/src/pages/ChatModule/RecommendationListCard/index.vue b/src/pages/ChatModule/RecommendationListCard/index.vue new file mode 100644 index 0000000..62a613b --- /dev/null +++ b/src/pages/ChatModule/RecommendationListCard/index.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/src/pages/ChatModule/RecommendationListCard/mocks.js b/src/pages/ChatModule/RecommendationListCard/mocks.js new file mode 100644 index 0000000..1eff210 --- /dev/null +++ b/src/pages/ChatModule/RecommendationListCard/mocks.js @@ -0,0 +1,21 @@ +export default { + title: "为你推荐", + subtitle: "按距离和热度排序", + badge: "3 个地点", + items: [ + { + id: "list-1", + title: "水上森林步道", + description: "轻松步行即可到达,适合拍照和短途散步。", + meta: "距你 620m", + cover: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?auto=format&fit=crop&w=600&q=80", + }, + { + id: "list-2", + title: "游客中心咖啡吧", + description: "可补水休息,靠近返程接驳点。", + meta: "步行 5 分钟", + cover: "https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?auto=format&fit=crop&w=600&q=80", + }, + ], +}; diff --git a/src/pages/ChatModule/RecommendationListCard/styles/index.scss b/src/pages/ChatModule/RecommendationListCard/styles/index.scss new file mode 100644 index 0000000..f53cd5a --- /dev/null +++ b/src/pages/ChatModule/RecommendationListCard/styles/index.scss @@ -0,0 +1,46 @@ +.recommendation-list-card { +} + +.recommendation-list-card__header { + margin-bottom: 12px; +} + +.recommendation-list-card__title { +} + +.recommendation-list-card__subtitle { + margin-top: 4px; +} + +.recommendation-list-card__list { +} + +.recommendation-list-card__item { +} + +.recommendation-list-card__item:active { + opacity: 0.86; +} + +.recommendation-list-card__item.is-disabled { + opacity: 0.55; +} + +.recommendation-list-card__thumb { +} + +.recommendation-list-card__content { + min-width: 0; +} + +.recommendation-list-card__name { +} + +.recommendation-list-card__desc { + margin-top: 5px; + line-height: 16px; +} + +.recommendation-list-card__meta { + margin-top: 7px; +} diff --git a/src/pages/ChatModule/RoutePlanCard/index.vue b/src/pages/ChatModule/RoutePlanCard/index.vue new file mode 100644 index 0000000..f5f1682 --- /dev/null +++ b/src/pages/ChatModule/RoutePlanCard/index.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/src/pages/ChatModule/RoutePlanCard/mocks.js b/src/pages/ChatModule/RoutePlanCard/mocks.js new file mode 100644 index 0000000..cb65ac8 --- /dev/null +++ b/src/pages/ChatModule/RoutePlanCard/mocks.js @@ -0,0 +1,14 @@ +export default { + title: "半日轻松游览路线", + duration: "约 2.5 小时", + cover: "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=600&q=80", + tags: ["亲子友好", "少走回头路", "含观光车"], + tipsTitle: "出行贴士", + nodes: [ + { id: "n1", title: "游客中心", description: "补给和领取地图", cover: "https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?auto=format&fit=crop&w=400&q=80" }, + { id: "n2", title: "翠谷瀑布", description: "核心观景点", cover: "https://images.unsplash.com/photo-1432405972618-c60b0225b8f9?auto=format&fit=crop&w=400&q=80" }, + { id: "n3", title: "水上森林", description: "慢游和拍照", cover: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?auto=format&fit=crop&w=400&q=80", tip: "推荐停留" }, + ], + connectors: ["步行约 5 分钟", "观光车约 6 分钟"], + tips: ["雨天注意栈道防滑。", "带老人小孩建议优先使用观光车。"], +}; diff --git a/src/pages/ChatModule/RoutePlanCard/styles/index.scss b/src/pages/ChatModule/RoutePlanCard/styles/index.scss new file mode 100644 index 0000000..f4ea6fd --- /dev/null +++ b/src/pages/ChatModule/RoutePlanCard/styles/index.scss @@ -0,0 +1,80 @@ +.route-plan-card { + width: 100%; +} + +.route-plan-card__summary { +} + +.route-plan-card__cover { +} + +.route-plan-card__summary-body { + min-width: 0; +} + +.route-plan-card__title { +} + +.route-plan-card__chips { + margin-top: 8px; +} + +.route-plan-card__arrow { + font-size: 24px; +} + +.route-plan-card__flow { +} + +.route-plan-card__node { +} + +.route-plan-card__num { + background: #10b981; +} + +.route-plan-card__node-img { +} + +.route-plan-card__node-body { + min-width: 0; +} + +.route-plan-card__node-title { +} + +.route-plan-card__node-desc { + margin: 4px 0 6px; +} + +.route-plan-card__connector { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 0 8px 22px; +} + +.route-plan-card__line { + width: 2px; + height: 24px; + border-radius: 4px; + background: #d1fae5; +} + +.route-plan-card__connector-text { +} + +.route-plan-card__tips { +} + +.route-plan-card__tips-title { + color: #92400e; + margin-bottom: 8px; +} + +.route-plan-card__tip { + color: #b45309; + font-size: 11px; + font-weight: 700; + line-height: 18px; +} diff --git a/src/pages/ChatModule/ScenicImageCard/index.vue b/src/pages/ChatModule/ScenicImageCard/index.vue new file mode 100644 index 0000000..d056203 --- /dev/null +++ b/src/pages/ChatModule/ScenicImageCard/index.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/pages/ChatModule/ScenicImageCard/mocks.js b/src/pages/ChatModule/ScenicImageCard/mocks.js new file mode 100644 index 0000000..f525d9e --- /dev/null +++ b/src/pages/ChatModule/ScenicImageCard/mocks.js @@ -0,0 +1,7 @@ +export default { + image: "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1000&q=80", + caption: { + title: "水上森林二号机位", + subtitle: "下午逆光较弱,适合拍摄树影和水面反射", + }, +}; diff --git a/src/pages/ChatModule/ScenicImageCard/styles/index.scss b/src/pages/ChatModule/ScenicImageCard/styles/index.scss new file mode 100644 index 0000000..18d4a81 --- /dev/null +++ b/src/pages/ChatModule/ScenicImageCard/styles/index.scss @@ -0,0 +1,30 @@ +.scenic-image-card__image-wrap { +} + +.scenic-image-card__image { + border-radius: 0; +} + +.scenic-image-card__caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 42px 16px 16px; + background: linear-gradient(180deg, rgba(15, 23, 42, 0) 0%, rgba(15, 23, 42, 0.72) 100%); +} + +.scenic-image-card__caption-title { + line-height: 20px; +} + +.scenic-image-card__caption-subtitle { + margin-top: 3px; + color: rgba(255, 255, 255, 0.72); +} + +.scenic-image-card__expand { + top: 12px; + right: 12px; + background: rgba(0, 0, 0, 0.32); +} diff --git a/src/pages/ChatModule/SharedVisual/ActionRow.vue b/src/pages/ChatModule/SharedVisual/ActionRow.vue new file mode 100644 index 0000000..66dd07a --- /dev/null +++ b/src/pages/ChatModule/SharedVisual/ActionRow.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/src/pages/ChatModule/SharedVisual/BadgePill.vue b/src/pages/ChatModule/SharedVisual/BadgePill.vue new file mode 100644 index 0000000..2d1cb41 --- /dev/null +++ b/src/pages/ChatModule/SharedVisual/BadgePill.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/src/pages/ChatModule/SharedVisual/CardShell.vue b/src/pages/ChatModule/SharedVisual/CardShell.vue new file mode 100644 index 0000000..c3938f6 --- /dev/null +++ b/src/pages/ChatModule/SharedVisual/CardShell.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/pages/ChatModule/SharedVisual/DetailShell.vue b/src/pages/ChatModule/SharedVisual/DetailShell.vue new file mode 100644 index 0000000..8596d32 --- /dev/null +++ b/src/pages/ChatModule/SharedVisual/DetailShell.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/src/pages/ChatModule/SharedVisual/MediaFrame.vue b/src/pages/ChatModule/SharedVisual/MediaFrame.vue new file mode 100644 index 0000000..68fa8cf --- /dev/null +++ b/src/pages/ChatModule/SharedVisual/MediaFrame.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/src/pages/ChatModule/SharedVisual/styles/index.scss b/src/pages/ChatModule/SharedVisual/styles/index.scss new file mode 100644 index 0000000..63c771c --- /dev/null +++ b/src/pages/ChatModule/SharedVisual/styles/index.scss @@ -0,0 +1,134 @@ +.visual-card-shell { + box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05); +} + +.visual-card-shell--soft { + background: rgba(255, 255, 255, 0.84); + box-shadow: 0 9px 34px rgba(27, 9, 91, 0.07); +} + +.visual-card-shell--detail { + border-radius: 20px; +} + +.visual-card-shell.is-pressable { + transition: transform 0.18s ease, opacity 0.18s ease; +} + +.visual-card-shell.is-pressable:active { + transform: scale(0.98); + opacity: 0.92; +} + +.visual-card-shell.is-disabled, +.visual-action-row.is-disabled { + opacity: 0.55; +} + +.visual-badge { + min-height: 20px; + padding: 2px 8px; + box-sizing: border-box; + line-height: 16px; +} + +.visual-badge--slate { + color: #475569; + background: #f1f5f9; +} + +.visual-badge--green { + color: #047857; + background: #ecfdf5; +} + +.visual-badge--amber { + color: #b45309; + background: #fffbeb; +} + +.visual-badge--rose { + color: #be123c; + background: #fff1f2; +} + +.visual-badge--blue { + color: #2563eb; + background: #eff6ff; +} + +.visual-badge--purple { + color: #7c3aed; + background: #f5f3ff; +} + +.visual-media { +} + +.visual-media__image, +.visual-media__empty { +} + +.visual-media__empty { + min-height: 96px; + background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); +} + +.visual-detail__header { + min-height: 48px; +} + +.visual-detail__back { + width: 30px; + height: 30px; + font-size: 22px; + line-height: 28px; +} + +.visual-detail__title { + min-width: 0; +} + +.visual-action-row { +} + +.visual-action-row__icon { +} + +.visual-action-row__icon--green { + color: #047857; + background: #ecfdf5; +} + +.visual-action-row__icon--blue { + color: #2563eb; + background: #eff6ff; +} + +.visual-action-row__icon--amber { + color: #b45309; + background: #fffbeb; +} + +.visual-action-row__icon--rose { + color: #be123c; + background: #fff1f2; +} + +.visual-action-row__body { + min-width: 0; +} + +.visual-action-row__title { +} + +.visual-action-row__subtitle { + margin-top: 4px; + color: #94a3b8; + font-size: 11px; + font-weight: 700; +} + +.visual-action-row__arrow { + font-size: 24px; +} diff --git a/src/pages/test/index.vue b/src/pages/test/index.vue new file mode 100644 index 0000000..830a26a --- /dev/null +++ b/src/pages/test/index.vue @@ -0,0 +1,191 @@ + + + + + diff --git a/src/static/scss/background.scss b/src/static/scss/background.scss index c187620..8e9a4fd 100644 --- a/src/static/scss/background.scss +++ b/src/static/scss/background.scss @@ -27,6 +27,46 @@ background-color: #f2f5f8; } +.bg-F8FAFC { + background-color: #f8fafc; +} + +.bg-F1F5F9 { + background-color: #f1f5f9; +} + +.bg-ECFDF5 { + background-color: #ecfdf5; +} + +.bg-FFFBEB { + background-color: #fffbeb; +} + +.bg-EFF6FF { + background-color: #eff6ff; +} + +.bg-F5F3FF { + background-color: #f5f3ff; +} + +.bg-FFF1F2 { + background-color: #fff1f2; +} + +.bg-CCFBF1 { + background-color: #ccfbf1; +} + +.bg-0F172A { + background-color: #0f172a; +} + +.bg-0F766E { + background-color: #0f766e; +} + .bg-FF3D60 { background-color: #ff3d60; } @@ -58,4 +98,4 @@ .bg-transparent { background-color: transparent; -} \ No newline at end of file +} diff --git a/src/static/scss/border.scss b/src/static/scss/border.scss index 6d496ac..51d8fff 100644 --- a/src/static/scss/border.scss +++ b/src/static/scss/border.scss @@ -19,6 +19,14 @@ border: 1px solid #fff; } +.border-F1F5F9 { + border: 1px solid #f1f5f9; +} + +.border-bottom-F1F5F9 { + border-bottom: 1px solid #f1f5f9; +} + .border-none { border: none; diff --git a/src/static/scss/colors.scss b/src/static/scss/colors.scss index 2ea82a1..6bac767 100644 --- a/src/static/scss/colors.scss +++ b/src/static/scss/colors.scss @@ -68,6 +68,54 @@ color: #d97706; } +.color-0F172A { + color: #0f172a; +} + +.color-1E293B { + color: #1e293b; +} + +.color-334155 { + color: #334155; +} + +.color-475569 { + color: #475569; +} + +.color-64748B { + color: #64748b; +} + +.color-CBD5E1 { + color: #cbd5e1; +} + +.color-2563EB { + color: #2563eb; +} + +.color-7C3AED { + color: #7c3aed; +} + +.color-E11D48 { + color: #e11d48; +} + +.color-0F766E { + color: #0f766e; +} + +.color-047857 { + color: #047857; +} + +.color-0891B2 { + color: #0891b2; +} + // text 颜色 .text-color-900 { color: $text-color-900; // #181B25 diff --git a/src/static/scss/display.scss b/src/static/scss/display.scss index f307efe..e4fbf50 100644 --- a/src/static/scss/display.scss +++ b/src/static/scss/display.scss @@ -14,3 +14,11 @@ .grid { display: grid; } + +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} diff --git a/src/static/scss/flex.scss b/src/static/scss/flex.scss index 248dfa5..7875f82 100644 --- a/src/static/scss/flex.scss +++ b/src/static/scss/flex.scss @@ -38,3 +38,27 @@ .flex-shrink-0 { flex-shrink: 0; } + +.gap-6 { + gap: 6px; +} + +.gap-8 { + gap: 8px; +} + +.gap-10 { + gap: 10px; +} + +.gap-12 { + gap: 12px; +} + +.gap-14 { + gap: 14px; +} + +.gap-16 { + gap: 16px; +} diff --git a/src/static/scss/font-size.scss b/src/static/scss/font-size.scss index 297bb94..4e53c0c 100644 --- a/src/static/scss/font-size.scss +++ b/src/static/scss/font-size.scss @@ -19,10 +19,18 @@ font-size: 12px; } +.font-size-13 { + font-size: 13px; +} + .font-size-14 { font-size: 14px; } +.font-size-15 { + font-size: 15px; +} + .font-size-16 { font-size: 16px; } @@ -39,6 +47,10 @@ font-size: 20px; } +.font-size-22 { + font-size: 22px; +} + .font-size-24 { font-size: 24px; } diff --git a/src/static/scss/font-weight.scss b/src/static/scss/font-weight.scss index be056e7..b1020c6 100644 --- a/src/static/scss/font-weight.scss +++ b/src/static/scss/font-weight.scss @@ -18,3 +18,11 @@ .font-700 { font-weight: 700; } + +.font-800 { + font-weight: 800; +} + +.font-900 { + font-weight: 900; +} diff --git a/src/static/scss/height.scss b/src/static/scss/height.scss index c4b2cc2..878a1e9 100644 --- a/src/static/scss/height.scss +++ b/src/static/scss/height.scss @@ -46,6 +46,18 @@ height: 44px; } +.h-42 { + height: 42px; +} + +.h-54 { + height: 54px; +} + +.h-60 { + height: 60px; +} + .h-64 { height: 64px; } @@ -54,10 +66,42 @@ height: 72px; } +.h-72 { + height: 72px; +} + .h-80 { height: 80px; } +.h-82 { + height: 82px; +} + .h-96 { height: 96px; } + +.h-108 { + height: 108px; +} + +.h-154 { + height: 154px; +} + +.h-164 { + height: 164px; +} + +.h-170 { + height: 170px; +} + +.h-178 { + height: 178px; +} + +.h-260 { + height: 260px; +} diff --git a/src/static/scss/position.scss b/src/static/scss/position.scss index d5cb467..0d064fa 100644 --- a/src/static/scss/position.scss +++ b/src/static/scss/position.scss @@ -18,3 +18,7 @@ .bottom-0 { bottom: 0; } + +.top-0 { + top: 0; +} diff --git a/src/static/scss/rounded.scss b/src/static/scss/rounded.scss index 2de66d5..d962c57 100644 --- a/src/static/scss/rounded.scss +++ b/src/static/scss/rounded.scss @@ -31,6 +31,10 @@ border-radius: 16px; } +.rounded-18 { + border-radius: 18px; +} + .rounded-20 { border-radius: 20px; } diff --git a/src/static/scss/width.scss b/src/static/scss/width.scss index e5bb9ee..1259961 100644 --- a/src/static/scss/width.scss +++ b/src/static/scss/width.scss @@ -34,6 +34,22 @@ width: 32px; } +.w-42 { + width: 42px; +} + +.w-44 { + width: 44px; +} + +.w-54 { + width: 54px; +} + +.w-72 { + width: 72px; +} + .w-50 { width: 50%; } @@ -52,4 +68,4 @@ .w-102 { width: 102px; -} \ No newline at end of file +}