From 71bc2db9856250bbe9c510c8aa6c114cdb917f2b Mon Sep 17 00:00:00 2001 From: ni ziyi <310925901@qq.com> Date: Fri, 12 Dec 2025 16:49:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 132 +++ .hbuilderx/launch.json | 23 + App.vue | 20 + DEBUG.md | 82 ++ DIAGNOSIS.md | 74 ++ FILES_CHECKLIST.md | 67 ++ ICONS_GUIDE.md | 174 ++++ QUICK_FIX.md | 83 ++ README.md | 158 +++ TROUBLESHOOTING.md | 47 + api/auth.js | 20 + api/bill.js | 35 + api/category.js | 30 + api/ocr.js | 15 + api/statistics.js | 25 + common/uni-ui.scss | 120 +++ components/uni-section/config.json | 12 + components/uni-section/readme.md | 30 + components/uni-section/uni-section.vue | 136 +++ index.html | 26 + main.js | 12 + manifest.json | 71 ++ package-lock.json | 906 ++++++++++++++++++ package.json | 21 + pages.json | 74 ++ pages/add/add.vue | 895 +++++++++++++++++ pages/add/list/list.vue | 158 +++ pages/bill/detail.vue | 492 ++++++++++ pages/category/category.vue | 337 +++++++ pages/index/index.vue | 297 ++++++ pages/login/login-simple.vue | 22 + pages/login/login.vue | 205 ++++ pages/statistics/statistics.vue | 246 +++++ static/css/common.css | 80 ++ static/tabbar/README.md | 111 +++ static/tabbar/add-active.png | Bin 0 -> 8685 bytes static/tabbar/add.png | Bin 0 -> 8594 bytes static/tabbar/home-active.png | Bin 0 -> 7833 bytes static/tabbar/home.png | Bin 0 -> 7657 bytes static/tabbar/statistic-active.png | Bin 0 -> 1737 bytes static/tabbar/statistics.png | Bin 0 -> 1729 bytes store/user.js | 47 + tsconfig.json | 27 + uni.scss | 75 ++ uniCloud-alipay/database/db_init.json | 427 +++++++++ .../database/opendb-news-articles.schema.json | 122 +++ uni_modules/uni-badge/changelog.md | 14 + .../components/uni-badge/uni-badge.vue | 252 +++++ uni_modules/uni-badge/package.json | 84 ++ uni_modules/uni-badge/readme.md | 58 ++ uni_modules/uni-config-center/changelog.md | 4 + uni_modules/uni-config-center/package.json | 80 ++ uni_modules/uni-config-center/readme.md | 93 ++ .../common/uni-config-center/index.js | 1 + .../common/uni-config-center/package.json | 13 + uni_modules/uni-icons/changelog.md | 4 + .../uni-icons/components/uni-icons/icons.js | 132 +++ .../components/uni-icons/uni-icons.uvue | 91 ++ .../components/uni-icons/uni-icons.vue | 71 ++ .../uni-icons/components/uni-icons/uni.ttf | Bin 0 -> 26164 bytes .../components/uni-icons/uniicons.css | 664 +++++++++++++ .../components/uni-icons/uniicons.ttf | Bin 0 -> 35824 bytes .../components/uni-icons/uniicons_file.ts | 664 +++++++++++++ .../components/uni-icons/uniicons_file_vue.js | 649 +++++++++++++ uni_modules/uni-icons/package.json | 82 ++ uni_modules/uni-icons/readme.md | 46 + uni_modules/uni-id/changelog.md | 24 + uni_modules/uni-id/package.json | 80 ++ uni_modules/uni-id/readme.md | 33 + .../cloudfunctions/common/uni-id/LICENSE.md | 201 ++++ .../cloudfunctions/common/uni-id/index.js | 1 + .../common/uni-id/package-lock.json | 11 + .../cloudfunctions/common/uni-id/package.json | 20 + uni_modules/uni-list/changelog.md | 7 + .../components/uni-list-ad/uni-list-ad.vue | 107 +++ .../uni-list-chat/uni-list-chat.scss | 58 ++ .../uni-list-chat/uni-list-chat.vue | 533 +++++++++++ .../uni-list-item/uni-list-item.vue | 438 +++++++++ .../uni-list/components/uni-list/uni-list.vue | 106 ++ .../components/uni-list/uni-refresh.vue | 65 ++ .../components/uni-list/uni-refresh.wxs | 87 ++ uni_modules/uni-list/package.json | 87 ++ uni_modules/uni-list/readme.md | 347 +++++++ uni_modules/uni-load-more/changelog.md | 6 + .../uni-load-more/uni-load-more.vue | 362 +++++++ uni_modules/uni-load-more/package.json | 82 ++ uni_modules/uni-load-more/readme.md | 70 ++ uni_modules/uni-scss/changelog.md | 8 + uni_modules/uni-scss/index.scss | 1 + uni_modules/uni-scss/package.json | 82 ++ uni_modules/uni-scss/readme.md | 4 + uni_modules/uni-scss/styles/index.scss | 7 + .../uni-scss/styles/setting/_border.scss | 3 + .../uni-scss/styles/setting/_color.scss | 66 ++ .../uni-scss/styles/setting/_radius.scss | 55 ++ .../uni-scss/styles/setting/_space.scss | 56 ++ .../uni-scss/styles/setting/_styles.scss | 167 ++++ .../uni-scss/styles/setting/_text.scss | 24 + .../uni-scss/styles/setting/_variables.scss | 146 +++ .../uni-scss/styles/tools/functions.scss | 19 + uni_modules/uni-scss/theme.scss | 31 + uni_modules/uni-scss/variables.scss | 62 ++ utils/date.js | 59 ++ utils/request.js | 185 ++++ 104 files changed, 12636 insertions(+) create mode 100644 .gitignore create mode 100644 .hbuilderx/launch.json create mode 100644 App.vue create mode 100644 DEBUG.md create mode 100644 DIAGNOSIS.md create mode 100644 FILES_CHECKLIST.md create mode 100644 ICONS_GUIDE.md create mode 100644 QUICK_FIX.md create mode 100644 README.md create mode 100644 TROUBLESHOOTING.md create mode 100644 api/auth.js create mode 100644 api/bill.js create mode 100644 api/category.js create mode 100644 api/ocr.js create mode 100644 api/statistics.js create mode 100644 common/uni-ui.scss create mode 100644 components/uni-section/config.json create mode 100644 components/uni-section/readme.md create mode 100644 components/uni-section/uni-section.vue create mode 100644 index.html create mode 100644 main.js create mode 100644 manifest.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pages.json create mode 100644 pages/add/add.vue create mode 100644 pages/add/list/list.vue create mode 100644 pages/bill/detail.vue create mode 100644 pages/category/category.vue create mode 100644 pages/index/index.vue create mode 100644 pages/login/login-simple.vue create mode 100644 pages/login/login.vue create mode 100644 pages/statistics/statistics.vue create mode 100644 static/css/common.css create mode 100644 static/tabbar/README.md create mode 100644 static/tabbar/add-active.png create mode 100644 static/tabbar/add.png create mode 100644 static/tabbar/home-active.png create mode 100644 static/tabbar/home.png create mode 100644 static/tabbar/statistic-active.png create mode 100644 static/tabbar/statistics.png create mode 100644 store/user.js create mode 100644 tsconfig.json create mode 100644 uni.scss create mode 100644 uniCloud-alipay/database/db_init.json create mode 100644 uniCloud-alipay/database/opendb-news-articles.schema.json create mode 100644 uni_modules/uni-badge/changelog.md create mode 100644 uni_modules/uni-badge/components/uni-badge/uni-badge.vue create mode 100644 uni_modules/uni-badge/package.json create mode 100644 uni_modules/uni-badge/readme.md create mode 100644 uni_modules/uni-config-center/changelog.md create mode 100644 uni_modules/uni-config-center/package.json create mode 100644 uni_modules/uni-config-center/readme.md create mode 100644 uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js create mode 100644 uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json create mode 100644 uni_modules/uni-icons/changelog.md create mode 100644 uni_modules/uni-icons/components/uni-icons/icons.js create mode 100644 uni_modules/uni-icons/components/uni-icons/uni-icons.uvue create mode 100644 uni_modules/uni-icons/components/uni-icons/uni-icons.vue create mode 100644 uni_modules/uni-icons/components/uni-icons/uni.ttf create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.css create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.ttf create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons_file.ts create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js create mode 100644 uni_modules/uni-icons/package.json create mode 100644 uni_modules/uni-icons/readme.md create mode 100644 uni_modules/uni-id/changelog.md create mode 100644 uni_modules/uni-id/package.json create mode 100644 uni_modules/uni-id/readme.md create mode 100644 uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md create mode 100644 uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js create mode 100644 uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package-lock.json create mode 100644 uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json create mode 100644 uni_modules/uni-list/changelog.md create mode 100644 uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue create mode 100644 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss create mode 100644 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue create mode 100644 uni_modules/uni-list/components/uni-list-item/uni-list-item.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-list.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-refresh.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-refresh.wxs create mode 100644 uni_modules/uni-list/package.json create mode 100644 uni_modules/uni-list/readme.md create mode 100644 uni_modules/uni-load-more/changelog.md create mode 100644 uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue create mode 100644 uni_modules/uni-load-more/package.json create mode 100644 uni_modules/uni-load-more/readme.md create mode 100644 uni_modules/uni-scss/changelog.md create mode 100644 uni_modules/uni-scss/index.scss create mode 100644 uni_modules/uni-scss/package.json create mode 100644 uni_modules/uni-scss/readme.md create mode 100644 uni_modules/uni-scss/styles/index.scss create mode 100644 uni_modules/uni-scss/styles/setting/_border.scss create mode 100644 uni_modules/uni-scss/styles/setting/_color.scss create mode 100644 uni_modules/uni-scss/styles/setting/_radius.scss create mode 100644 uni_modules/uni-scss/styles/setting/_space.scss create mode 100644 uni_modules/uni-scss/styles/setting/_styles.scss create mode 100644 uni_modules/uni-scss/styles/setting/_text.scss create mode 100644 uni_modules/uni-scss/styles/setting/_variables.scss create mode 100644 uni_modules/uni-scss/styles/tools/functions.scss create mode 100644 uni_modules/uni-scss/theme.scss create mode 100644 uni_modules/uni-scss/variables.scss create mode 100644 utils/date.js create mode 100644 utils/request.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f19c63 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +# ====================== +# 操作系统 & 编辑器 +# ====================== +.DS_Store +Thumbs.db +ehthumbs.db +Icon? +desktop.ini +*.swp +*.swo +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.idea/ +*.sublime-project +*.sublime-workspace + +# ====================== +# 日志 & 临时文件 +# ====================== +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# ====================== +# 依赖目录 +# ====================== +node_modules/ +jspm_packages/ +bower_components/ +.mvn/ +target/ +build/ +dist/ +out/ +coverage/ + +# ====================== +# 环境变量 & 敏感配置 +# ====================== +.env +.env.local +.env.development.local +.env.test.local +.env.production.local +config/local.* +secrets.yml + +# ====================== +# 构建产物(前端) +# ====================== +/public/build +/public/hot +/public/dist +/assets/*.min.js +/assets/*.min.css + +# ====================== +# Python +# ====================== +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +venv/ +ENV/ +.env + +# ====================== +# Java / Maven / Gradle +# ====================== +*.class +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar +hs_err_pid* +.gradle/ +build/ +!gradle/wrapper/gradle-wrapper.jar + +# ====================== +# Docker +# ====================== +.dockerignore +docker-compose.override.yml + +# ====================== +# 其他 +# ====================== +*.tmp +*.bak +*.orig +*.rej +*~ +.swp +.lock +.nyc_output/ +.grunt/ +gulpfile.js +package-lock.json # 可选:有些团队会提交它 +yarn.lock # 可选:通常建议提交 yarn.lock +pnpm-lock.yaml # 可选:通常建议提交 +/node_modules/ diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..6dea3f8 --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,23 @@ +{ + "version" : "2.0.0", + "configurations" : [ + { + "name" : "运行到H5", + "request" : "launch", + "runtime" : "h5", + "type" : "uni-app", + "url" : "http://localhost:8080" + }, + { + "default" : { + "launchtype" : "local" + }, + "h5" : { + "launchtype" : "local" + }, + "provider" : "alipay", + "type" : "uniCloud" + } + ] +} + diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..5148124 --- /dev/null +++ b/App.vue @@ -0,0 +1,20 @@ + + + diff --git a/DEBUG.md b/DEBUG.md new file mode 100644 index 0000000..1717c61 --- /dev/null +++ b/DEBUG.md @@ -0,0 +1,82 @@ +# 调试指南 - 空白页面问题 + +## 可能的原因和解决方案 + +### 1. 检查浏览器控制台 +打开浏览器开发者工具(F12),查看Console标签页,看是否有JavaScript错误。 + +### 2. 检查网络请求 +在Network标签页,查看是否有资源加载失败(红色标记)。 + +### 3. 检查uni-app配置 +确保项目被HBuilderX识别为uni-app项目: +- `manifest.json` 存在且配置正确 +- `pages.json` 存在且配置正确 +- `App.vue` 存在 + +### 4. 尝试以下操作 + +#### 方法一:使用HBuilderX的标准运行方式 +1. 关闭当前运行 +2. 在HBuilderX中:运行 → 运行到浏览器 → Chrome +3. 不要使用命令行运行 + +#### 方法二:检查项目类型 +确保HBuilderX识别项目类型为"uni-app项目": +- 右键项目根目录 +- 查看项目类型 + +#### 方法三:清除缓存 +```bash +cd frontend +rm -rf node_modules/.vite +rm -rf .hbuilderx +``` + +#### 方法四:检查页面路由 +确保 `pages.json` 中第一个页面路径正确: +```json +{ + "pages": [ + { + "path": "pages/index/index", // 确保这个文件存在 + ... + } + ] +} +``` + +### 5. 常见错误 + +#### 错误:Cannot find module 'vue' +**解决**:执行 `npm install vue pinia` + +#### 错误:Failed to parse .vue files +**解决**:已安装 `@vitejs/plugin-vue` + +#### 错误:空白页面 +**可能原因**: +- main.js格式不正确 +- App.vue缺少template +- 页面路由配置错误 +- JavaScript运行时错误 + +### 6. 调试步骤 + +1. **打开浏览器控制台**(F12) +2. **查看Console错误** +3. **查看Network请求** +4. **检查页面元素**(Elements标签) +5. **提供错误信息**以便进一步排查 + +## 如果仍然空白 + +请提供以下信息: +1. 浏览器控制台的错误信息(Console标签) +2. 网络请求状态(Network标签,是否有404或500错误) +3. HBuilderX的运行日志 +4. 页面源代码(右键页面 → 查看网页源代码) + + + + diff --git a/DIAGNOSIS.md b/DIAGNOSIS.md new file mode 100644 index 0000000..5fbc858 --- /dev/null +++ b/DIAGNOSIS.md @@ -0,0 +1,74 @@ +# 诊断指南 - 页面空白问题 + +## 当前状态 +- ✅ main.js 已加载完成 +- ❌ 页面显示空白 +- ❌ Console没有页面相关的输出 + +## 可能的原因 + +### 1. uni-app路由系统未初始化 +uni-app在HBuilderX中运行时,需要特殊的路由系统。如果路由系统没有正确初始化,页面就不会显示。 + +### 2. 页面组件未加载 +如果控制台没有"登录页面加载成功"的输出,说明页面组件根本没有加载。 + +### 3. App.vue的template是空的 +App.vue只有一个空的view标签,uni-app可能无法正确渲染。 + +## 排查步骤 + +### 步骤1:检查控制台输出 +请查看浏览器控制台,告诉我: +- 是否有"登录页面加载成功"的输出? +- 是否有"App Launch"的输出? +- 是否有任何错误信息? + +### 步骤2:检查Network标签 +查看Network标签,检查: +- `pages/login/login-simple.vue` 是否加载? +- 是否有404错误? +- 是否有其他失败的请求? + +### 步骤3:检查页面元素 +在Elements标签中,检查: +- `#app` 元素是否存在? +- 是否有内容被渲染? +- 是否有uni-app的路由容器? + +## 解决方案 + +### 方案1:检查HBuilderX项目类型 +确保HBuilderX识别为"uni-app项目": +- 右键项目文件夹 +- 查看项目类型 +- 如果不是uni-app,可能需要重新创建项目 + +### 方案2:使用HBuilderX的标准运行方式 +- 不要使用命令行运行 +- 使用HBuilderX菜单:运行 → 运行到浏览器 +- 确保选择的是"uni-app"运行方式 + +### 方案3:检查manifest.json +确保manifest.json配置正确: +- vueVersion: "3" +- 其他配置正确 + +## 请提供以下信息 + +1. **控制台输出**: + - 是否有"登录页面加载成功"? + - 是否有"App Launch"? + - 是否有任何错误? + +2. **Network标签**: + - login-simple.vue是否加载? + - 状态码是什么? + +3. **Elements标签**: + - #app元素的内容是什么? + - 是否有任何内容被渲染? + + + + diff --git a/FILES_CHECKLIST.md b/FILES_CHECKLIST.md new file mode 100644 index 0000000..f0f40df --- /dev/null +++ b/FILES_CHECKLIST.md @@ -0,0 +1,67 @@ +# 前端文件清单 + +## 已创建的文件 + +### 核心配置文件 +- ✅ `package.json` - 项目依赖配置 +- ✅ `pages.json` - 页面路由配置 +- ✅ `manifest.json` - uni-app应用配置 +- ✅ `main.js` - 应用入口文件 +- ✅ `App.vue` - 应用根组件 +- ✅ `vite.config.js` - Vite构建配置 +- ✅ `tsconfig.json` - TypeScript配置 +- ✅ `uni.scss` - uni-app样式变量 + +### 工具类文件 +- ✅ `utils/request.js` - HTTP请求封装(包含JWT token管理) +- ✅ `utils/date.js` - 日期工具函数 + +### 状态管理 +- ✅ `store/user.js` - 用户状态管理(Pinia store) + +### API接口封装 +- ✅ `api/auth.js` - 认证相关API(注册、登录) +- ✅ `api/bill.js` - 账单相关API(CRUD操作) +- ✅ `api/category.js` - 分类相关API +- ✅ `api/statistics.js` - 统计相关API +- ✅ `api/ocr.js` - OCR识别API + +### 页面文件 +- ✅ `pages/login/login.vue` - 登录/注册页面 +- ✅ `pages/index/index.vue` - 首页(账单列表) +- ✅ `pages/add/add.vue` - 添加账单页面(手动+OCR) +- ✅ `pages/statistics/statistics.vue` - 统计页面 +- ✅ `pages/category/category.vue` - 分类管理页面 + +### 样式文件 +- ✅ `static/css/common.css` - 全局公共样式 + +## 可选文件(需要时添加) + +### TabBar图标(可选) +如果需要显示底部导航栏图标,需要添加以下图片文件: +- `static/tabbar/home.png` - 首页图标 +- `static/tabbar/home-active.png` - 首页选中图标 +- `static/tabbar/add.png` - 记账图标 +- `static/tabbar/add-active.png` - 记账选中图标 +- `static/tabbar/statistics.png` - 统计图标 +- `static/tabbar/statistics-active.png` - 统计选中图标 + +如果没有这些图标,tabBar会显示文字但不显示图标,功能不受影响。 + +## 文件说明 + +所有核心功能文件都已创建完成,项目可以直接运行。如果遇到问题,请检查: + +1. 是否已安装依赖:`npm install` +2. 后端服务是否已启动 +3. API地址配置是否正确(`utils/request.js`中的BASE_URL) + + + + + + + + + diff --git a/ICONS_GUIDE.md b/ICONS_GUIDE.md new file mode 100644 index 0000000..469e728 --- /dev/null +++ b/ICONS_GUIDE.md @@ -0,0 +1,174 @@ +# 图标文件使用指南 + +## 📋 项目中使用的图标文件 + +### 1. TabBar 底部导航图标(必需) + +在 `pages.json` 中配置的 TabBar 需要以下 6 个图标文件: + +| 图标名称 | 用途 | 路径 | +|---------|------|------| +| `home.png` | 首页(未选中) | `static/tabbar/home.png` | +| `home-active.png` | 首页(选中) | `static/tabbar/home-active.png` | +| `add.png` | 记账(未选中) | `static/tabbar/add.png` | +| `add-active.png` | 记账(选中) | `static/tabbar/add-active.png` | +| `statistics.png` | 统计(未选中) | `static/tabbar/statistics.png` | +| `statistics-active.png` | 统计(选中) | `static/tabbar/statistics-active.png` | + +**图标规格**: +- 尺寸:81px × 81px(@2x)或 40px × 40px(@1x) +- 格式:PNG(支持透明背景) +- 颜色: + - 未选中:#7A7E83(灰色) + - 选中:#667eea(紫色) + +### 2. 分类图标(使用 Emoji,无需文件) + +代码中使用 Emoji 作为分类图标,例如: +- 📦 默认分类 +- 🍔 餐饮 +- 👕 服装 +- 🏠 住房 +- 🚗 交通 +- 等等... + +这些图标存储在数据库中,不需要图标文件。 + +### 3. 功能图标(使用 Emoji,无需文件) + +- 📷 上传图片图标(在 OCR 页面) + +## 🚀 快速获取图标的方法 + +### 方法1:使用在线图标库(推荐) + +#### IconFont(阿里巴巴图标库) +1. 访问:https://www.iconfont.cn/ +2. 注册/登录账号 +3. 搜索关键词: + - "首页" 或 "home" + - "添加" 或 "add" 或 "plus" + - "统计" 或 "statistics" 或 "chart" +4. 选择图标,点击下载 +5. 选择 PNG 格式,尺寸选择 81×81 +6. 下载后重命名并放入 `static/tabbar/` 目录 + +#### Flaticon +1. 访问:https://www.flaticon.com/ +2. 搜索图标 +3. 下载 PNG 格式(免费账号需要注明来源) + +### 方法2:使用 AI 生成图标 + +使用 ChatGPT、Midjourney 等 AI 工具生成图标: + +**提示词示例**: +``` +生成一个简单的首页图标,极简风格,紫色主题,透明背景,81x81像素,PNG格式 +``` + +### 方法3:临时解决方案(使用文字图标) + +如果暂时没有图标文件,可以修改 `pages.json`,移除图标路径,只显示文字: + +```json +{ + "tabBar": { + "list": [ + { + "pagePath": "pages/index/index", + "text": "首页" + // 移除 iconPath 和 selectedIconPath + } + ] + } +} +``` + +### 方法4:使用 uni-app 内置图标 + +uni-app 支持使用字体图标,可以集成 iconfont: + +1. 访问 https://www.iconfont.cn/ +2. 创建项目,添加图标 +3. 下载字体文件 +4. 在项目中引入字体文件 +5. 使用类名引用图标 + +## 📥 推荐的免费图标资源 + +1. **IconFont** - https://www.iconfont.cn/ + - 中文界面,搜索方便 + - 免费使用,需登录 + +2. **Flaticon** - https://www.flaticon.com/ + - 图标丰富 + - 免费使用需注明来源 + +3. **Icons8** - https://icons8.com/ + - 图标质量高 + - 部分免费 + +4. **Material Icons** - https://fonts.google.com/icons + - Google 官方图标库 + - 完全免费 + +5. **Font Awesome** - https://fontawesome.com/ + - 图标库丰富 + - 部分免费 + +## 🎨 图标设计建议 + +### 风格统一 +- 所有图标使用相同的设计风格 +- 线条粗细一致 +- 圆角或直角统一 + +### 颜色方案 +- 未选中:灰色(#7A7E83) +- 选中:紫色(#667eea,与主题色一致) + +### 尺寸规范 +- TabBar 图标:81px × 81px(@2x) +- 确保图标在选中和未选中状态下清晰可辨 + +## ⚠️ 注意事项 + +1. **文件路径**:图标文件必须放在 `static/tabbar/` 目录下 +2. **文件命名**:文件名必须与 `pages.json` 中的配置完全一致(区分大小写) +3. **文件格式**:使用 PNG 格式,支持透明背景 +4. **文件大小**:建议单个图标文件不超过 50KB +5. **缺失处理**:如果图标文件不存在,TabBar 可能无法正常显示 + +## 🔧 快速测试 + +创建占位图标文件进行测试: + +1. 创建 6 个 81×81px 的纯色 PNG 图片 +2. 未选中状态使用灰色,选中状态使用紫色 +3. 放入 `static/tabbar/` 目录 +4. 运行项目查看效果 + +## 📝 图标文件清单 + +请确保以下文件存在: + +``` +frontend/static/tabbar/ +├── home.png ✅ 需要创建 +├── home-active.png ✅ 需要创建 +├── add.png ✅ 需要创建 +├── add-active.png ✅ 需要创建 +├── statistics.png ✅ 需要创建 +└── statistics-active.png ✅ 需要创建 +``` + +## 💡 快速开始 + +**最快的方式**: +1. 访问 https://www.iconfont.cn/ +2. 搜索并下载 6 个图标(首页、添加、统计各 2 个) +3. 重命名为对应文件名 +4. 放入 `static/tabbar/` 目录 +5. 完成! + diff --git a/QUICK_FIX.md b/QUICK_FIX.md new file mode 100644 index 0000000..35c58b8 --- /dev/null +++ b/QUICK_FIX.md @@ -0,0 +1,83 @@ +# 快速修复指南 - 登录页不显示 + +## 问题分析 + +uni-app项目在HBuilderX中使用Vite时,可能存在路由系统不兼容的问题。 + +## 解决方案 + +### 方案一:使用HBuilderX标准运行方式(推荐) + +1. **删除或重命名 `vite.config.js`** + - HBuilderX有自己的构建系统,不需要Vite配置 + - 已重命名为 `vite.config.js.bak` + +2. **在HBuilderX中运行** + - 运行 → 运行到浏览器 → Chrome + - 不要使用命令行运行 + +3. **检查项目类型** + - 确保HBuilderX识别为"uni-app项目" + - 右键项目 → 查看项目类型 + +### 方案二:检查浏览器控制台 + +1. **打开浏览器开发者工具**(F12) +2. **查看Console标签**,看是否有错误: + - 路由错误 + - 模块加载错误 + - JavaScript运行时错误 + +3. **查看Network标签**,检查: + - `main.js` 是否加载成功 + - `pages/login/login.vue` 是否加载成功 + - 是否有404错误 + +### 方案三:简化测试 + +如果仍然不显示,创建一个最简单的测试页面: + +在 `pages/login/login.vue` 中,先测试最基础的内容: + +```vue + + + +``` + +### 方案四:检查文件路径 + +确保文件路径正确: +- `pages/login/login.vue` 文件存在 +- `pages.json` 中路径配置正确:`"path": "pages/login/login"` + +## 常见问题 + +### Q: 页面完全空白? +A: 检查浏览器控制台,看是否有JavaScript错误 + +### Q: 显示"加载中"? +A: 检查 `index.html` 是否还有加载提示,已移除 + +### Q: 路由不工作? +A: 确保使用HBuilderX的标准运行方式,不要使用纯Vite + +## 下一步 + +1. 删除 `vite.config.js.bak`(如果方案一不行) +2. 检查浏览器控制台错误 +3. 提供具体的错误信息以便进一步排查 + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..8af346b --- /dev/null +++ b/README.md @@ -0,0 +1,158 @@ +# 强宝爱记账前端 + +基于 uni-app + Vue 3 开发的记账应用前端项目。 + +## 功能特性 + +- ✅ 用户登录/注册 +- ✅ 手动记账 +- ✅ OCR识别记账(支持截图识别金额) +- ✅ 账单列表展示(按日期分组) +- ✅ 统计功能(按日/周/月统计) +- ✅ 分类管理 + +## 技术栈 + +- **框架**: uni-app + Vue 3 +- **状态管理**: Pinia +- **UI组件**: uni-ui +- **HTTP请求**: uni.request 封装 + +## 项目结构 + +``` +frontend/ +├── pages/ # 页面 +│ ├── login/ # 登录页 +│ ├── index/ # 首页(账单列表) +│ ├── add/ # 添加账单 +│ └── statistics/ # 统计页 +├── api/ # API接口封装 +│ ├── auth.js # 认证接口 +│ ├── bill.js # 账单接口 +│ ├── category.js # 分类接口 +│ ├── statistics.js # 统计接口 +│ └── ocr.js # OCR接口 +├── store/ # Pinia状态管理 +│ └── user.js # 用户状态 +├── utils/ # 工具函数 +│ ├── request.js # HTTP请求封装 +│ └── date.js # 日期工具 +├── static/ # 静态资源 +├── App.vue # 应用根组件 +├── main.js # 入口文件 +└── pages.json # 页面配置 +``` + +## 开发说明 + +### 环境要求 + +- Node.js >= 14 +- HBuilderX(推荐)或 uni-app CLI + +### 安装依赖 + +```bash +npm install +``` + +### 运行项目 + +#### HBuilderX + +1. 使用 HBuilderX 打开项目 +2. 选择运行 -> 运行到浏览器 -> Chrome + +#### CLI + +```bash +npm run dev:h5 +``` + +### 配置后端API地址 + +修改 `utils/request.js` 中的 `BASE_URL`: + +```javascript +const BASE_URL = process.env.NODE_ENV === 'development' + ? 'http://localhost:8080/api' // 开发环境 + : 'https://your-api-domain.com/api' // 生产环境 +``` + +## 页面说明 + +### 登录页 (`pages/login/login.vue`) + +- 支持登录和注册 +- 自动保存token和用户信息 +- 登录成功后跳转到首页 + +### 首页 (`pages/index/index.vue`) + +- 显示本月收支统计 +- 账单列表按日期分组展示 +- 支持下拉刷新 +- 点击账单可查看详情(待完善) + +### 添加账单页 (`pages/add/add.vue`) + +- **手动记账**: 手动输入分类、金额、日期、备注 +- **OCR识别**: + - 选择图片(相机/相册) + - 上传识别 + - 自动填充金额、商户、日期 + - 可手动修改识别结果 + +### 统计页 (`pages/statistics/statistics.vue`) + +- 按日/周/月切换统计 +- 显示总收入、总支出、余额 +- 分类统计展示(带进度条) + +## API接口 + +### 认证接口 + +- `POST /api/auth/register` - 注册 +- `POST /api/auth/login` - 登录 + +### 账单接口 + +- `GET /api/bills` - 获取账单列表 +- `POST /api/bills` - 创建账单 +- `GET /api/bills/:id` - 获取账单详情 +- `PUT /api/bills/:id` - 更新账单 +- `DELETE /api/bills/:id` - 删除账单 + +### 分类接口 + +- `GET /api/categories` - 获取分类列表 +- `POST /api/categories` - 创建分类 +- `PUT /api/categories/:id` - 更新分类 +- `DELETE /api/categories/:id` - 删除分类 + +### 统计接口 + +- `GET /api/statistics/daily` - 按日统计 +- `GET /api/statistics/weekly` - 按周统计 +- `GET /api/statistics/monthly` - 按月统计 + +### OCR接口 + +- `POST /api/ocr/recognize` - OCR识别 + +## 注意事项 + +1. **登录状态**: 所有页面都会检查登录状态,未登录会自动跳转到登录页 +2. **Token管理**: Token存储在本地存储中,过期后会自动跳转登录 +3. **图片上传**: OCR功能需要上传图片,注意图片大小限制 +4. **平台差异**: 注意H5和App平台的API差异,部分功能可能需要平台判断 + +## 待完善功能 + +- [ ] 账单编辑功能 +- [ ] 账单删除功能 +- [ ] 分类管理页面 +- [ ] 账单详情页面 +- [ ] 图表展示(echarts集成) diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md new file mode 100644 index 0000000..eaca192 --- /dev/null +++ b/TROUBLESHOOTING.md @@ -0,0 +1,47 @@ +# 故障排查指南 + +## 问题:Failed to resolve import "vue" + +### 解决方案 + +1. **确保依赖已安装** + ```bash + cd frontend + npm install vue pinia + ``` + +2. **清除缓存并重新安装** + ```bash + cd frontend + npm cache clean --force + rm -rf node_modules + npm install + ``` + +3. **在HBuilderX中运行** + - 不要使用命令行运行 + - 直接在HBuilderX中:运行 → 运行到浏览器 + - HBuilderX会自动处理依赖 + +4. **检查node_modules** + - 确保 `frontend/node_modules/vue` 目录存在 + - 如果不存在,执行 `npm install vue` + +5. **如果仍然报错** + - 尝试删除 `vite.config.js`(HBuilderX项目可能不需要) + - 或者简化 `vite.config.js` 配置 + +## 常见问题 + +### Q: HBuilderX提示缺少index.html? +A: 已创建 `index.html` 文件,如果还有问题,检查文件是否在根目录。 + +### Q: 依赖安装失败? +A: 对于HBuilderX项目,通常不需要手动安装uni-app相关依赖,只需要安装业务依赖(vue、pinia)。 + +### Q: API请求失败? +A: 确保后端服务已启动,检查 `utils/request.js` 中的API地址配置。 + + + + diff --git a/api/auth.js b/api/auth.js new file mode 100644 index 0000000..1ca299a --- /dev/null +++ b/api/auth.js @@ -0,0 +1,20 @@ +import { post } from '../utils/request' + +// 用户注册 +export function register(data) { + return post('/auth/register', data) +} + +// 用户登录 +export function login(data) { + return post('/auth/login', data) +} + + + + + + + + + diff --git a/api/bill.js b/api/bill.js new file mode 100644 index 0000000..3886be7 --- /dev/null +++ b/api/bill.js @@ -0,0 +1,35 @@ +import { get, post, put, del } from '../utils/request' + +// 获取账单列表 +export function getBills(params) { + return get('/bills', params) +} + +// 获取账单详情 +export function getBill(id) { + return get(`/bills/${id}`) +} + +// 创建账单 +export function createBill(data) { + return post('/bills', data) +} + +// 更新账单 +export function updateBill(id, data) { + return put(`/bills/${id}`, data) +} + +// 删除账单 +export function deleteBill(id) { + return del(`/bills/${id}`) +} + + + + + + + + + diff --git a/api/category.js b/api/category.js new file mode 100644 index 0000000..feaab8b --- /dev/null +++ b/api/category.js @@ -0,0 +1,30 @@ +import { get, post, put, del } from '../utils/request' + +// 获取分类列表 +export function getCategories(type) { + return get('/categories', type ? { type } : {}) +} + +// 创建分类 +export function createCategory(data) { + return post('/categories', data) +} + +// 更新分类 +export function updateCategory(id, data) { + return put(`/categories/${id}`, data) +} + +// 删除分类 +export function deleteCategory(id) { + return del(`/categories/${id}`) +} + + + + + + + + + diff --git a/api/ocr.js b/api/ocr.js new file mode 100644 index 0000000..fd75465 --- /dev/null +++ b/api/ocr.js @@ -0,0 +1,15 @@ +import { upload } from '../utils/request' + +// OCR识别 +export function recognizeImage(filePath) { + return upload('/ocr/recognize', filePath) +} + + + + + + + + + diff --git a/api/statistics.js b/api/statistics.js new file mode 100644 index 0000000..b772543 --- /dev/null +++ b/api/statistics.js @@ -0,0 +1,25 @@ +import { get } from '../utils/request' + +// 按日期范围统计 +export function getDailyStatistics(startDate, endDate) { + return get('/statistics/daily', { startDate, endDate }) +} + +// 按周统计 +export function getWeeklyStatistics(weekStart) { + return get('/statistics/weekly', { weekStart }) +} + +// 按月统计 +export function getMonthlyStatistics(year, month) { + return get('/statistics/monthly', { year, month }) +} + + + + + + + + + diff --git a/common/uni-ui.scss b/common/uni-ui.scss new file mode 100644 index 0000000..6ba0990 --- /dev/null +++ b/common/uni-ui.scss @@ -0,0 +1,120 @@ + +.uni-flex { + display: flex; +} + +.uni-flex-row { + @extend .uni-flex; + flex-direction: row; + box-sizing: border-box; +} + +.uni-flex-column { + @extend .uni-flex; + flex-direction: column; +} + +.uni-color-gary { + color: #3b4144; +} + +/* 标题 */ +.uni-title { + display: flex; + margin-bottom: $uni-spacing-col-base; + font-size: $uni-font-size-lg; + font-weight: bold; + color: #3b4144; +} + +.uni-title-sub { + display: flex; + // margin-bottom: $uni-spacing-col-base; + font-size: $uni-font-size-base; + font-weight: 500; + color: #3b4144; +} + +/* 描述 额外文本 */ +.uni-note { + margin-top: 10px; + color: #999; + font-size: $uni-font-size-sm; +} + +/* 列表内容 */ +.uni-list-box { + @extend .uni-flex-row; + flex: 1; + margin-top: 10px; +} + +/* 略缩图 */ +.uni-thumb { + flex-shrink: 0; + margin-right: $uni-spacing-row-base; + width: 125px; + height: 75px; + border-radius: $uni-border-radius-lg; + overflow: hidden; + border: 1px #f5f5f5 solid; + image { + width: 100%; + height: 100%; + } +} + +.uni-media-box { + @extend .uni-flex-row; + // margin-bottom: $uni-spacing-col-base; + border-radius: $uni-border-radius-lg; + overflow: hidden; + .uni-thumb { + margin: 0; + margin-left: 4px; + flex-shrink: 1; + width: 33%; + border-radius:0; + &:first-child { + margin: 0; + } + } +} + +/* 内容 */ +.uni-content { + @extend .uni-flex-column; + justify-content: space-between; +} + +/* 列表footer */ +.uni-footer { + @extend .uni-flex-row; + justify-content: space-between; + margin-top: $uni-spacing-col-lg; +} +.uni-footer-text { + font-size: $uni-font-size-sm; + color: $uni-text-color-grey; + margin-left: 5px; +} + +/* 标签 */ + +.uni-tag { + flex-shrink: 0; + padding: 0 5px; + border: 1px $uni-border-color solid; + margin-right: $uni-spacing-row-sm; + border-radius: $uni-border-radius-base; + background: $uni-bg-color-grey; + color: $uni-text-color; + font-size: $uni-font-size-sm; +} + +/* 链接 */ +.uni-link { + margin-left: 10px; + color: $uni-text-color; + text-decoration: underline; +} diff --git a/components/uni-section/config.json b/components/uni-section/config.json new file mode 100644 index 0000000..43d5d01 --- /dev/null +++ b/components/uni-section/config.json @@ -0,0 +1,12 @@ +{ + "id": "99999", + "name": "Section", + "desc": "标题栏", + "edition": "0.0.1", + "url": "section", + "type": "布局组件", + "path": "https://ext.dcloud.net.cn/plugin?id=", + "hidden": true, + "test":true, + "update_log": [] +} diff --git a/components/uni-section/readme.md b/components/uni-section/readme.md new file mode 100644 index 0000000..c5998fa --- /dev/null +++ b/components/uni-section/readme.md @@ -0,0 +1,30 @@ +### Section 标题栏 + +标题栏,用于显示标题,组件名:``uni-section``,代码块: uSection。 + +### 使用方式 + +在 ``script`` 中引用组件 + +```javascript +import uniSection from "@/components/uni-section/uni-section.vue" +export default { + components: {uniSection} +} +``` + +在 ``template`` 中使用组件 + +```html + + + +``` + +### 属性说明 + +|属性名 |类型 |默认值 |说明 | +|--- |---- |--- |--- | +|type |String |- |标题装饰类型 ,可选值:line(竖线)、circle(圆形)| +|title |String |- |主标题 | +|sub-title |String |- |副标题 | diff --git a/components/uni-section/uni-section.vue b/components/uni-section/uni-section.vue new file mode 100644 index 0000000..52a1567 --- /dev/null +++ b/components/uni-section/uni-section.vue @@ -0,0 +1,136 @@ + + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..e5515b1 --- /dev/null +++ b/index.html @@ -0,0 +1,26 @@ + + + + + + 强宝爱记账 + + + +
+ + + diff --git a/main.js b/main.js new file mode 100644 index 0000000..4501e2c --- /dev/null +++ b/main.js @@ -0,0 +1,12 @@ +import { createSSRApp } from 'vue' +import { createPinia } from 'pinia' +import App from './App.vue' + +export function createApp() { + const app = createSSRApp(App) + const pinia = createPinia() + app.use(pinia) + return { + app + } +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..fab259f --- /dev/null +++ b/manifest.json @@ -0,0 +1,71 @@ +{ + "name": "强宝爱记账", + "appid": "__UNI__ACCOUNTING", + "description": "智能记账应用,支持OCR识别账单", + "versionName": "1.0.0", + "versionCode": "100", + "transformPx": false, + "app-plus": { + "usingComponents": true, + "nvueStyleCompiler": "uni-app", + "compilerVersion": 3, + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 + }, + "modules": {}, + "distribute": { + "android": { + "permissions": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "ios": {}, + "sdkConfigs": {} + } + }, + "quickapp": {}, + "mp-weixin": { + "appid": "", + "setting": { + "urlCheck": false + }, + "usingComponents": true + }, + "mp-alipay": { + "usingComponents": true + }, + "mp-baidu": { + "usingComponents": true + }, + "mp-toutiao": { + "usingComponents": true + }, + "uniStatistics": { + "enable": false + }, + "vueVersion": "3", + "h5": { + "router": { + "mode": "hash" + } + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..79bbeea --- /dev/null +++ b/package-lock.json @@ -0,0 +1,906 @@ +{ + "name": "accounting-app", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "accounting-app", + "version": "1.0.0", + "dependencies": { + "@dcloudio/uni-app": "^2.0.2-4080720251210002", + "@dcloudio/uni-h5": "^2.0.2-4080720251210002", + "pinia": "^2.3.1", + "vue": "^3.5.25" + }, + "devDependencies": { + "@types/node": "^24.10.2", + "@vitejs/plugin-vue": "^4.0.0", + "typescript": "^5.2.2", + "vite": "^4.5.14" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@dcloudio/uni-app": { + "version": "2.0.2-4080720251210002", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app/-/uni-app-2.0.2-4080720251210002.tgz", + "integrity": "sha512-FUw/bJJwBPl/scKBog21wusICrU9T4TFwyKKVbtNbWIO98IBzjRIin0mmwzhqHNL1kZO0LbwnoRe7LtusW8LQw==", + "peerDependencies": { + "@dcloudio/types": "^3.0.15", + "@vue/composition-api": "^1.7.0" + } + }, + "node_modules/@dcloudio/uni-h5": { + "version": "2.0.2-4080720251210002", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-2.0.2-4080720251210002.tgz", + "integrity": "sha512-yBYX2rvX+03eVjkmzNfWetMW5jjhz+7B643Otjs7IOp+KXVSpslAwLO3F5kKhaBQQXGFJ9Tn7f4DEtrQZkAxKg==", + "dependencies": { + "base64-arraybuffer": "^0.2.0", + "intersection-observer": "^0.7.0", + "pako": "^1.0.11", + "postcss-urlrewrite": "^0.3.0", + "safe-area-insets": "^1.4.1" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" + }, + "node_modules/@types/node": { + "version": "24.10.2", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-24.10.2.tgz", + "integrity": "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==", + "dev": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz", + "integrity": "sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.25.tgz", + "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.25", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz", + "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==", + "dependencies": { + "@vue/compiler-core": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz", + "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.25", + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz", + "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, + "node_modules/@vue/reactivity": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.25.tgz", + "integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==", + "dependencies": { + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.25.tgz", + "integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz", + "integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/runtime-core": "3.5.25", + "@vue/shared": "3.5.25", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.25.tgz", + "integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==", + "dependencies": { + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "vue": "3.5.25" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz", + "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==" + }, + "node_modules/base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/intersection-observer": { + "version": "0.7.0", + "resolved": "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.7.0.tgz", + "integrity": "sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg==", + "deprecated": "The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019." + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/pinia": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.3.1.tgz", + "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-helpers": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/postcss-helpers/-/postcss-helpers-0.3.3.tgz", + "integrity": "sha512-VumiUcrpbxGlTBNQj6fUOkb/HNRUk/xYz8bNlhgVOdvk3yWEy4B+0nlDUZZM9mTVZ5bJoxUy7WT6z/4E7oMTgw==", + "dependencies": { + "urijs": "^1.18.12" + }, + "engines": { + "node": ">=0.12.9" + } + }, + "node_modules/postcss-urlrewrite": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/postcss-urlrewrite/-/postcss-urlrewrite-0.3.0.tgz", + "integrity": "sha512-504S/dMa7a0n1yghE2I6fxY/DfMUM+w9qsFaoYnXE8KsCofmKLlA7PKbR+wtdEJ0N00Z1lGYxX/oFz13xArcLQ==", + "dependencies": { + "postcss-helpers": "^0.3.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/rollup": { + "version": "3.29.5", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-area-insets": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/safe-area-insets/-/safe-area-insets-1.4.1.tgz", + "integrity": "sha512-r/nRWTjFGhhm3w1Z6Kd/jY11srN+lHt2mNl1E/emQGW8ic7n3Avu4noibklfSM+Y34peNphHD/BSZecav0sXYQ==" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true + }, + "node_modules/urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmmirror.com/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" + }, + "node_modules/vite": { + "version": "4.5.14", + "resolved": "https://registry.npmmirror.com/vite/-/vite-4.5.14.tgz", + "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.5.25", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.25.tgz", + "integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-sfc": "3.5.25", + "@vue/runtime-dom": "3.5.25", + "@vue/server-renderer": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c8d1a05 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "accounting-app", + "version": "1.0.0", + "description": "强宝爱记账", + "main": "main.js", + "scripts": { + "dev:h5": "npm run serve", + "serve": "uni serve", + "build:h5": "uni build" + }, + "dependencies": { + "@dcloudio/uni-app": "^2.0.2-4080720251210002", + "@dcloudio/uni-h5": "^2.0.2-4080720251210002", + "pinia": "^2.3.1", + "vue": "^3.5.25" + }, + "devDependencies": { + "@types/node": "^24.10.2", + "typescript": "^5.2.2" + } +} \ No newline at end of file diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..1af33d4 --- /dev/null +++ b/pages.json @@ -0,0 +1,74 @@ +{ + "easycom": { + "autoscan": true, + "custom": { + "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue" + } + }, + "pages": [ + { + "path": "pages/login/login", + "style": { + "navigationBarTitleText": "登录", + "navigationStyle": "custom" + } + }, + { + "path": "pages/index/index", + "style": { + "navigationBarTitleText": "首页", + "enablePullDownRefresh": true + } + }, + { + "path": "pages/add/add", + "style": { + "navigationBarTitleText": "添加账单" + } + }, + { + "path": "pages/statistics/statistics", + "style": { + "navigationBarTitleText": "统计" + } + }, + { + "path": "pages/bill/detail", + "style": { + "navigationBarTitleText": "编辑账单" + } + } + ], + "tabBar": { + "color": "#7A7E83", + "selectedColor": "#667eea", + "borderStyle": "black", + "backgroundColor": "#ffffff", + "list": [ + { + "pagePath": "pages/index/index", + "iconPath": "static/tabbar/home.png", + "selectedIconPath": "static/tabbar/home-active.png", + "text": "首页" + }, + { + "pagePath": "pages/add/add", + "iconPath": "static/tabbar/add.png", + "selectedIconPath": "static/tabbar/add-active.png", + "text": "记账" + }, + { + "pagePath": "pages/statistics/statistics", + "iconPath": "static/tabbar/statistics.png", + "selectedIconPath": "static/tabbar/statistic-active.png", + "text": "统计" + } + ] + }, + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "强宝爱记账", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8" + } +} diff --git a/pages/add/add.vue b/pages/add/add.vue new file mode 100644 index 0000000..0471079 --- /dev/null +++ b/pages/add/add.vue @@ -0,0 +1,895 @@ +