diff --git a/.gitignore b/.gitignore
index 62bab23..658a179 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,8 @@ dist
*.ntvs*
*.njsproj
*.sln
-*.sw?
\ No newline at end of file
+*.sw?
+# Dev artifacts
+.playwright-mcp/
+*.png
+!src/static/**/*.png
diff --git a/CLAUDE.md b/CLAUDE.md
index 3a89b32..3756c55 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -150,3 +150,63 @@ dist/build/mp-weixin/ # 用微信开发者工具导入此目录
4. **条件编译**:`#ifdef MP-WEIXIN` 包裹微信特有逻辑
5. **隐私协议**:`App.vue` 中 `wx.getPrivacySetting` 检查,未同意前不能调授权 API
6. **微信开发者工具调试**:需勾选「不校验合法域名」才能请求 localhost
+
+
+You tend to converge toward generic, "on distribution" outputs.
+In frontend design, this creates what users call the "AI slop"
+aesthetic. Avoid this: make creative, distinctive frontends that
+surprise and delight. Focus on:
+
+Typography: Choose fonts that are beautiful, unique, and interesting.
+Avoid generic fonts like Arial and Inter; opt instead for distinctive
+choices that elevate the frontend's aesthetics.
+
+Color & Theme: Commit to a cohesive aesthetic. Use CSS variables for
+consistency. Dominant colors with sharp accents outperform timid,
+evenly-distributed palettes.
+
+Motion: Use animations for effects and micro-interactions.
+Focus on high-impact moments: one well-orchestrated page load
+with staggered reveals creates more delight than scattered
+micro-interactions.
+
+Backgrounds: Create atmosphere and depth rather than defaulting
+to solid colors. Layer CSS gradients, use geometric patterns,
+or add contextual effects.
+
+Avoid generic AI-generated aesthetics:
+- Overused font families (Inter, Roboto, Arial, system fonts)
+- Clichéd color schemes (particularly purple gradients on white)
+- Predictable layouts and component patterns
+- Cookie-cutter design that lacks context-specific character
+
+Interpret creatively and make unexpected choices that feel
+genuinely designed for the context.
+
+
+
+Typography instantly signals quality. Avoid boring, generic fonts.
+
+Never use: Inter, Roboto, Open Sans, Lato, default system fonts
+
+Impact choices:
+- Code aesthetic: JetBrains Mono, Fira Code, Space Grotesk
+- Editorial: Playfair Display, Crimson Pro, Fraunces
+- Startup: Clash Display, Satoshi, Cabinet Grotesk
+- Technical: IBM Plex family, Source Sans 3
+- Distinctive: Bricolage Grotesque, Obviously, Newsreader
+
+Pairing principle: High contrast = interesting.
+Display + monospace, serif + geometric sans.
+
+Use extremes: 100/200 weight vs 800/900, not 400 vs 600.
+Size jumps of 3x+, not 1.5x.
+
+
+# Design System
+
+Always refer to DESIGN.md when generating or modifying any UI component.
+Use only colors, fonts, and spacing values defined in DESIGN.md.
+Do not invent new values or use defaults from any framework.
+Match component states (hover, focus, active, disabled) to patterns
+in DESIGN.md.
\ No newline at end of file
diff --git a/src/App.vue b/src/App.vue
index d0b04bc..0fb575a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -4,15 +4,20 @@ import { useUserStore } from './store/user'
onLaunch(() => {
// #ifdef MP-WEIXIN
- wx.getPrivacySetting({
- success: (res: any) => {
- if (res.needAuthorization) {
- uni.setStorageSync('needPrivacy', true)
- } else {
- uni.removeStorageSync('needPrivacy')
- }
- }
- })
+ // 仅真机检查隐私协议,模拟器中跳过(getPrivacySetting 在模拟器会触发框架级 timeout)
+ const sysInfo = uni.getSystemInfoSync()
+ if (sysInfo.platform !== 'devtools' && wx.getPrivacySetting) {
+ wx.getPrivacySetting({
+ success: (res: any) => {
+ if (res.needAuthorization) {
+ uni.setStorageSync('needPrivacy', true)
+ } else {
+ uni.removeStorageSync('needPrivacy')
+ }
+ },
+ fail: () => {},
+ })
+ }
// #endif
const userStore = useUserStore()
@@ -25,9 +30,10 @@ onLaunch(() => {
})
-
diff --git a/src/components/design-button.vue b/src/components/design-button.vue
new file mode 100644
index 0000000..39960d4
--- /dev/null
+++ b/src/components/design-button.vue
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/design-card.vue b/src/components/design-card.vue
new file mode 100644
index 0000000..5abbb36
--- /dev/null
+++ b/src/components/design-card.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/design-input.vue b/src/components/design-input.vue
new file mode 100644
index 0000000..a36a49d
--- /dev/null
+++ b/src/components/design-input.vue
@@ -0,0 +1,122 @@
+
+
+ {{ label }}
+
+
+
+
+
+ {{ errorMessage }}
+
+
+
+
+
+
+
diff --git a/src/components/section-label.vue b/src/components/section-label.vue
new file mode 100644
index 0000000..82c2ebe
--- /dev/null
+++ b/src/components/section-label.vue
@@ -0,0 +1,43 @@
+
+
+
+ {{ text }}
+
+
+
+
+
+
diff --git a/src/packages/user/pages/card/list.vue b/src/packages/user/pages/card/list.vue
index bf1781e..e568a4e 100644
--- a/src/packages/user/pages/card/list.vue
+++ b/src/packages/user/pages/card/list.vue
@@ -1,9 +1,19 @@
-
-
-
+
+
+
+
+
+ 旅游卡
+ 畅游赣湘,一卡在手
+
+
{{ cat.label }}
+
+
+
+
+
+
- 加载中...
-
-
+
+
+ 加载中...
+
+
+
+
+
+ 暂无符合条件的年卡
+ 换个关键词试试
@@ -34,7 +57,6 @@ import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getCardList } from '../../../../api/card'
import CardItem from '../../../../components/card-item.vue'
-import EmptyState from '../../../../components/empty-state.vue'
import type { CardInfo } from '../../../../api/types'
const cardList = ref([])
@@ -42,7 +64,6 @@ const loading = ref(false)
const keyword = ref('')
const currentCategory = ref('')
-/** 分类选项 */
const categories = [
{ label: '全部', value: '' },
{ label: '旅游年卡', value: 'travel' },
@@ -50,7 +71,6 @@ const categories = [
{ label: '情侣年卡', value: 'couple' }
]
-/** 获取年卡列表 */
async function fetchCardList(params?: { keyword?: string; category?: string }) {
loading.value = true
try {
@@ -60,34 +80,197 @@ async function fetchCardList(params?: { keyword?: string; category?: string }) {
}
}
-/** 页面加载时获取年卡列表 */
onLoad(() => {
fetchCardList()
})
-/** 执行搜索 */
function handleSearch() {
fetchCardList({ keyword: keyword.value, category: currentCategory.value })
}
-/** 选择分类 */
function selectCategory(value: string) {
currentCategory.value = value
handleSearch()
}
-/** 跳转年卡详情 */
function goDetail(card: CardInfo) {
uni.navigateTo({ url: `/packages/user/pages/card/detail?id=${card.id}` })
}
-
diff --git a/src/pages.json b/src/pages.json
index 132a3ae..53cabea 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -78,11 +78,11 @@
"navigationBarTextStyle": "black",
"navigationBarTitleText": "爱上萍乡",
"navigationBarBackgroundColor": "#FFFFFF",
- "backgroundColor": "#F5F5F5"
+ "backgroundColor": "#FAFAFA"
},
"tabBar": {
"color": "#7A7E83",
- "selectedColor": "#4A90D9",
+ "selectedColor": "#3c9cff",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"list": [
@@ -94,9 +94,9 @@
},
{
"pagePath": "pages/qrcode/index",
- "text": "入园码",
- "iconPath": "static/tabbar/qrcode.png",
- "selectedIconPath": "static/tabbar/qrcode-active.png"
+ "text": "旅游卡",
+ "iconPath": "static/tabbar/card.png",
+ "selectedIconPath": "static/tabbar/card-active.png"
},
{
"pagePath": "pages/profile/index",
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index 70e3640..05e5572 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -1,92 +1,98 @@
-
-
+
+
+
-
+
爱上萍乡
- 赣湘之间 · 发现旅途美好
-
-
-
-
- 搜索景区、活动...
-
+ 赣湘之间 · 发现旅途美好
-
+
-
-
-
- 公告
+
+
+
+ 公告
- {{ item.content }}
+ {{ item.content }}
-
-
-
- 工会会员专属
- 赣湘全域旅游年卡
-
- ¥
- 300
- /套卡(2张)
-
-
- 22家景区免门票
- 武功山·方特·君澜温泉
- 覆盖萍乡/长沙/株洲/湘潭
-
-
- 立即抢购
-
-
-
-
-
- 大学生·市民专属
- 超级玩家卡
-
- ¥
- 198
-
-
- 40家景区免门票
- 武功山·方特·韶山·滴水洞
- 含外骨骼登山·青年旅社等
-
-
- 立即抢购
-
+
+
+
+
+
+
+ 大学生·市民专属
+ 超级玩家卡
+
+
+ ¥
+ 198
+
+
+ 景区总价值
+ ¥3800+
+
+
+ 40家景区免门票 · 武功山·方特·韶山·滴水洞
+
+ 立即抢购
+
+
-
+
-