From e9f182f2d3ed3e32fa2ff63c2a1ba85d622e31fc Mon Sep 17 00:00:00 2001 From: xuqiuyun <1113560936@qq.com> Date: Thu, 18 Sep 2025 18:23:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=A4=E4=B8=AA=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- insurance_mini_program/app.json | 72 + .../application-result/application-result.js | 181 + .../application-result.json | 7 + .../application-result.wxml | 129 + .../application-result.wxss | 289 + .../pages/application/application.js | 384 + .../pages/application/application.json | 7 + .../pages/application/application.wxml | 259 + .../pages/application/application.wxss | 454 ++ .../pages/claim-detail/claim-detail.js | 339 + .../pages/claim-detail/claim-detail.json | 7 + .../pages/claim-detail/claim-detail.wxml | 170 + .../pages/claim-detail/claim-detail.wxss | 414 ++ insurance_mini_program/pages/claims/claims.js | 260 + .../pages/claims/claims.json | 8 + .../pages/claims/claims.wxml | 120 + .../pages/claims/claims.wxss | 342 + insurance_mini_program/pages/index/index.js | 213 + insurance_mini_program/pages/index/index.json | 7 + insurance_mini_program/pages/index/index.wxml | 106 + insurance_mini_program/pages/index/index.wxss | 233 + insurance_mini_program/pages/login/login.js | 404 ++ insurance_mini_program/pages/login/login.json | 7 + insurance_mini_program/pages/login/login.wxml | 165 + insurance_mini_program/pages/login/login.wxss | 356 + insurance_mini_program/pages/my/my.js | 336 + insurance_mini_program/pages/my/my.json | 7 + insurance_mini_program/pages/my/my.wxml | 132 + insurance_mini_program/pages/my/my.wxss | 219 + .../pages/policies/policies.js | 316 + .../pages/policies/policies.json | 8 + .../pages/policies/policies.wxml | 155 + .../pages/policies/policies.wxss | 374 + .../pages/policy-detail/policy-detail.js | 283 + .../pages/policy-detail/policy-detail.json | 7 + .../pages/policy-detail/policy-detail.wxml | 199 + .../pages/policy-detail/policy-detail.wxss | 392 ++ .../pages/product-detail/product-detail.js | 426 ++ .../pages/product-detail/product-detail.json | 8 + .../pages/product-detail/product-detail.wxml | 177 + .../pages/product-detail/product-detail.wxss | 575 ++ .../pages/products/products.js | 346 + .../pages/products/products.json | 8 + .../pages/products/products.wxml | 152 + .../pages/products/products.wxss | 367 + insurance_mini_program/sitemap.json | 9 + .../src/pages/index/index.vue | 186 +- .../farm-monitor-dashboard/API_INTEGRATION.md | 241 + .../farm-monitor-dashboard/API_TEST_GUIDE.md | 123 + .../farm-monitor-dashboard/AUTH_FIX_README.md | 88 + .../COLLAR_API_INTEGRATION.md | 127 + .../COLLAR_PAGINATION_SEARCH_FEATURES.md | 184 + .../EARTAG_CRUD_FEATURES.md | 187 + .../FIELD_MAPPING_GUIDE.md | 168 + .../LOGIN_PAGE_README.md | 112 + .../NETWORK_ERROR_FIX.md | 121 + .../PAGINATION_FIELD_MAPPING_FIX.md | 123 + .../PASSWORD_LOGIN_README.md | 175 + .../REGISTER_PAGE_README.md | 162 + .../ROUTER_FIX_README.md | 107 + .../SEARCH_FUNCTIONALITY.md | 175 + .../SMS_LOGIN_README.md | 139 + .../SYNTAX_ERROR_FIX.md | 60 + .../farm-monitor-dashboard/TOKEN_ERROR_FIX.md | 141 + .../farm-monitor-dashboard/package-lock.json | 6190 +++-------------- .../farm-monitor-dashboard/package.json | 18 +- .../farm-monitor-dashboard/public/favicon.svg | 4 + .../farm-monitor-dashboard/public/index.html | 18 + .../farm-monitor-dashboard/src/App.vue | 95 +- .../farm-monitor-dashboard/src/app.scss | 5 +- .../src/components/AuthTest.vue | 388 ++ .../src/components/EarTag.vue | 1415 ++++ .../src/components/Home.vue | 594 ++ .../src/components/Login.vue | 553 ++ .../src/components/PasswordLogin.vue | 756 ++ .../src/components/Production.vue | 377 + .../src/components/Profile.vue | 385 + .../src/components/Register.vue | 630 ++ .../src/components/SmartAnkle.vue | 547 ++ .../src/components/SmartCollar.vue | 1374 ++++ .../src/components/SmartHost.vue | 553 ++ .../src/components/SmsLogin.vue | 618 ++ .../farm-monitor-dashboard/src/main.js | 36 +- .../src/router/index.js | 127 + .../src/services/ankleService.js | 149 + .../src/services/authService.js | 409 +- .../src/services/collarService.js | 286 + .../src/services/earTagService.js | 319 + .../src/services/hostService.js | 161 + .../src/services/smartDeviceService.js | 140 + .../src/services/smsService.js | 141 + .../src/services/userService.js | 190 + .../farm-monitor-dashboard/src/utils/auth.js | 294 +- .../farm-monitor-dashboard/test-auth.html | 42 + .../farm-monitor-dashboard/test-collar-api.js | 150 + .../test-collar-pagination-search.js | 197 + .../test-pagination-fix.js | 146 + .../farm-monitor-dashboard/vue.config.js | 12 +- 98 files changed, 23288 insertions(+), 6079 deletions(-) create mode 100644 insurance_mini_program/app.json create mode 100644 insurance_mini_program/pages/application-result/application-result.js create mode 100644 insurance_mini_program/pages/application-result/application-result.json create mode 100644 insurance_mini_program/pages/application-result/application-result.wxml create mode 100644 insurance_mini_program/pages/application-result/application-result.wxss create mode 100644 insurance_mini_program/pages/application/application.js create mode 100644 insurance_mini_program/pages/application/application.json create mode 100644 insurance_mini_program/pages/application/application.wxml create mode 100644 insurance_mini_program/pages/application/application.wxss create mode 100644 insurance_mini_program/pages/claim-detail/claim-detail.js create mode 100644 insurance_mini_program/pages/claim-detail/claim-detail.json create mode 100644 insurance_mini_program/pages/claim-detail/claim-detail.wxml create mode 100644 insurance_mini_program/pages/claim-detail/claim-detail.wxss create mode 100644 insurance_mini_program/pages/claims/claims.js create mode 100644 insurance_mini_program/pages/claims/claims.json create mode 100644 insurance_mini_program/pages/claims/claims.wxml create mode 100644 insurance_mini_program/pages/claims/claims.wxss create mode 100644 insurance_mini_program/pages/index/index.js create mode 100644 insurance_mini_program/pages/index/index.json create mode 100644 insurance_mini_program/pages/index/index.wxml create mode 100644 insurance_mini_program/pages/index/index.wxss create mode 100644 insurance_mini_program/pages/login/login.js create mode 100644 insurance_mini_program/pages/login/login.json create mode 100644 insurance_mini_program/pages/login/login.wxml create mode 100644 insurance_mini_program/pages/login/login.wxss create mode 100644 insurance_mini_program/pages/my/my.js create mode 100644 insurance_mini_program/pages/my/my.json create mode 100644 insurance_mini_program/pages/my/my.wxml create mode 100644 insurance_mini_program/pages/my/my.wxss create mode 100644 insurance_mini_program/pages/policies/policies.js create mode 100644 insurance_mini_program/pages/policies/policies.json create mode 100644 insurance_mini_program/pages/policies/policies.wxml create mode 100644 insurance_mini_program/pages/policies/policies.wxss create mode 100644 insurance_mini_program/pages/policy-detail/policy-detail.js create mode 100644 insurance_mini_program/pages/policy-detail/policy-detail.json create mode 100644 insurance_mini_program/pages/policy-detail/policy-detail.wxml create mode 100644 insurance_mini_program/pages/policy-detail/policy-detail.wxss create mode 100644 insurance_mini_program/pages/product-detail/product-detail.js create mode 100644 insurance_mini_program/pages/product-detail/product-detail.json create mode 100644 insurance_mini_program/pages/product-detail/product-detail.wxml create mode 100644 insurance_mini_program/pages/product-detail/product-detail.wxss create mode 100644 insurance_mini_program/pages/products/products.js create mode 100644 insurance_mini_program/pages/products/products.json create mode 100644 insurance_mini_program/pages/products/products.wxml create mode 100644 insurance_mini_program/pages/products/products.wxss create mode 100644 insurance_mini_program/sitemap.json create mode 100644 mini_program/farm-monitor-dashboard/API_INTEGRATION.md create mode 100644 mini_program/farm-monitor-dashboard/API_TEST_GUIDE.md create mode 100644 mini_program/farm-monitor-dashboard/AUTH_FIX_README.md create mode 100644 mini_program/farm-monitor-dashboard/COLLAR_API_INTEGRATION.md create mode 100644 mini_program/farm-monitor-dashboard/COLLAR_PAGINATION_SEARCH_FEATURES.md create mode 100644 mini_program/farm-monitor-dashboard/EARTAG_CRUD_FEATURES.md create mode 100644 mini_program/farm-monitor-dashboard/FIELD_MAPPING_GUIDE.md create mode 100644 mini_program/farm-monitor-dashboard/LOGIN_PAGE_README.md create mode 100644 mini_program/farm-monitor-dashboard/NETWORK_ERROR_FIX.md create mode 100644 mini_program/farm-monitor-dashboard/PAGINATION_FIELD_MAPPING_FIX.md create mode 100644 mini_program/farm-monitor-dashboard/PASSWORD_LOGIN_README.md create mode 100644 mini_program/farm-monitor-dashboard/REGISTER_PAGE_README.md create mode 100644 mini_program/farm-monitor-dashboard/ROUTER_FIX_README.md create mode 100644 mini_program/farm-monitor-dashboard/SEARCH_FUNCTIONALITY.md create mode 100644 mini_program/farm-monitor-dashboard/SMS_LOGIN_README.md create mode 100644 mini_program/farm-monitor-dashboard/SYNTAX_ERROR_FIX.md create mode 100644 mini_program/farm-monitor-dashboard/TOKEN_ERROR_FIX.md create mode 100644 mini_program/farm-monitor-dashboard/public/favicon.svg create mode 100644 mini_program/farm-monitor-dashboard/public/index.html create mode 100644 mini_program/farm-monitor-dashboard/src/components/AuthTest.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/EarTag.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/Home.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/Login.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/PasswordLogin.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/Production.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/Profile.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/Register.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/SmartAnkle.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/SmartCollar.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/SmartHost.vue create mode 100644 mini_program/farm-monitor-dashboard/src/components/SmsLogin.vue create mode 100644 mini_program/farm-monitor-dashboard/src/router/index.js create mode 100644 mini_program/farm-monitor-dashboard/src/services/ankleService.js create mode 100644 mini_program/farm-monitor-dashboard/src/services/collarService.js create mode 100644 mini_program/farm-monitor-dashboard/src/services/earTagService.js create mode 100644 mini_program/farm-monitor-dashboard/src/services/hostService.js create mode 100644 mini_program/farm-monitor-dashboard/src/services/smartDeviceService.js create mode 100644 mini_program/farm-monitor-dashboard/src/services/smsService.js create mode 100644 mini_program/farm-monitor-dashboard/src/services/userService.js create mode 100644 mini_program/farm-monitor-dashboard/test-auth.html create mode 100644 mini_program/farm-monitor-dashboard/test-collar-api.js create mode 100644 mini_program/farm-monitor-dashboard/test-collar-pagination-search.js create mode 100644 mini_program/farm-monitor-dashboard/test-pagination-fix.js diff --git a/insurance_mini_program/app.json b/insurance_mini_program/app.json new file mode 100644 index 0000000..5040234 --- /dev/null +++ b/insurance_mini_program/app.json @@ -0,0 +1,72 @@ +{ + "pages": [ + "pages/index/index", + "pages/login/login", + "pages/products/products", + "pages/product-detail/product-detail", + "pages/application/application", + "pages/application-result/application-result", + "pages/my/my", + "pages/policies/policies", + "pages/policy-detail/policy-detail", + "pages/claims/claims", + "pages/claim-detail/claim-detail" + ], + "window": { + "navigationBarTextStyle": "white", + "navigationBarTitleText": "保险服务", + "navigationBarBackgroundColor": "#1890ff", + "backgroundColor": "#f5f5f5", + "backgroundTextStyle": "dark", + "enablePullDownRefresh": false, + "onReachBottomDistance": 50, + "restartStrategy": "homePage" + }, + "tabBar": { + "color": "#666666", + "selectedColor": "#1890ff", + "backgroundColor": "#ffffff", + "borderStyle": "white", + "list": [ + { + "pagePath": "pages/index/index", + "text": "首页" + }, + { + "pagePath": "pages/products/products", + "text": "产品" + }, + { + "pagePath": "pages/my/my", + "text": "我的" + } + ] + }, + "networkTimeout": { + "request": 10000, + "downloadFile": 10000, + "uploadFile": 10000, + "connectSocket": 10000 + }, + "permission": { + "scope.userLocation": { + "desc": "获取位置信息用于投保地址定位和风险评估" + }, + "scope.camera": { + "desc": "使用相机拍摄证件照片和事故现场照片" + }, + "scope.album": { + "desc": "选择相册中的证件照片和事故现场照片" + }, + "scope.record": { + "desc": "录制语音说明用于理赔申请" + } + }, + "lazyCodeLoading": "requiredComponents", + "style": "v2", + "sitemapLocation": "sitemap.json", + "debug": false, + "requiredPrivateInfos": [ + "getLocation" + ] +} \ No newline at end of file diff --git a/insurance_mini_program/pages/application-result/application-result.js b/insurance_mini_program/pages/application-result/application-result.js new file mode 100644 index 0000000..7b6867a --- /dev/null +++ b/insurance_mini_program/pages/application-result/application-result.js @@ -0,0 +1,181 @@ +// pages/application-result/application-result.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 申请结果状态 + resultStatus: 'success', // success 或 error + + // 结果消息 + resultMessage: '', + + // 申请信息 + applicationInfo: {}, + + // 温馨提示 + tips: [] + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('申请结果页加载', options) + const { productId, status } = options + + this.setData({ + resultStatus: status || 'success' + }) + + this.loadApplicationInfo(productId) + this.loadTips() + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('申请结果页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('申请结果页显示') + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('申请结果页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('申请结果页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保险申请结果', + path: '/pages/application-result/application-result', + imageUrl: '/static/images/share-result.jpg' + } + }, + + /** + * 加载申请信息 + */ + loadApplicationInfo(productId) { + console.log('加载申请信息:', productId) + + // 模拟申请信息 + const mockApplicationInfo = { + productName: '综合意外伤害保险', + applicationNo: 'APP' + Date.now(), + applicantName: '张先生', + coverageAmount: 50, + premium: 299, + applicationTime: this.formatDate(new Date()) + } + + // 根据状态设置不同的消息 + let resultMessage = '' + if (this.data.resultStatus === 'success') { + resultMessage = '您的投保申请已成功提交,请及时完成保费支付以确保保单生效。' + } else { + resultMessage = '投保申请提交失败,请检查信息后重新申请或联系客服。' + } + + this.setData({ + applicationInfo: mockApplicationInfo, + resultMessage: resultMessage + }) + }, + + /** + * 加载温馨提示 + */ + loadTips() { + const tips = this.data.resultStatus === 'success' ? [ + '请确保在24小时内完成保费支付,逾期将自动取消申请', + '支付完成后,电子保单将在1-3个工作日内生成', + '保单生效后,您可以在"我的保单"中查看详细信息', + '如有任何疑问,请及时联系客服热线:400-123-4567' + ] : [ + '请仔细检查填写的个人信息是否准确', + '确保身份证号和手机号格式正确', + '健康告知问题请如实回答', + '如问题持续存在,请联系客服协助处理' + ] + + this.setData({ tips }) + }, + + /** + * 格式化日期 + */ + formatDate(date) { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + const hours = String(date.getHours()).padStart(2, '0') + const minutes = String(date.getMinutes()).padStart(2, '0') + + return `${year}-${month}-${day} ${hours}:${minutes}` + }, + + /** + * 返回首页 + */ + goToHome() { + console.log('返回首页') + wx.switchTab({ + url: '/pages/index/index' + }) + }, + + /** + * 查看保单 + */ + goToPolicies() { + console.log('查看保单') + wx.switchTab({ + url: '/pages/policies/policies' + }) + }, + + /** + * 重新申请 + */ + retryApplication() { + console.log('重新申请') + wx.navigateBack({ + delta: 2 + }) + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/application-result/application-result.json b/insurance_mini_program/pages/application-result/application-result.json new file mode 100644 index 0000000..305246b --- /dev/null +++ b/insurance_mini_program/pages/application-result/application-result.json @@ -0,0 +1,7 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "申请结果", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5" +} \ No newline at end of file diff --git a/insurance_mini_program/pages/application-result/application-result.wxml b/insurance_mini_program/pages/application-result/application-result.wxml new file mode 100644 index 0000000..1e0c9d0 --- /dev/null +++ b/insurance_mini_program/pages/application-result/application-result.wxml @@ -0,0 +1,129 @@ + + + + + + {{resultStatus === 'success' ? '✓' : '✗'}} + + + {{resultStatus === 'success' ? '申请提交成功' : '申请提交失败'}} + {{resultMessage}} + + + + + 申请信息 + + + + 产品名称 + {{applicationInfo.productName}} + + + + 申请单号 + {{applicationInfo.applicationNo}} + + + + 申请人 + {{applicationInfo.applicantName}} + + + + 保险金额 + ¥{{applicationInfo.coverageAmount}}万 + + + + 应缴保费 + ¥{{applicationInfo.premium}} + + + + 申请时间 + {{applicationInfo.applicationTime}} + + + + + + + 下一步操作 + + + + 💳 + + 支付保费 + 请在24小时内完成保费支付 + + > + + + + 📄 + + 查看保单 + 支付完成后可查看电子保单 + + > + + + + 🔄 + + 重新申请 + 检查信息后重新提交申请 + + > + + + + 📞 + + 联系客服 + 如有疑问请联系客服 + + > + + + + + + + 温馨提示 + + + 💡 + {{item}} + + + + + + + + + + + + + \ No newline at end of file diff --git a/insurance_mini_program/pages/application-result/application-result.wxss b/insurance_mini_program/pages/application-result/application-result.wxss new file mode 100644 index 0000000..da2b946 --- /dev/null +++ b/insurance_mini_program/pages/application-result/application-result.wxss @@ -0,0 +1,289 @@ +/* pages/application-result/application-result.wxss */ +.container { + background: #f5f5f5; + min-height: 100vh; + padding-bottom: 120rpx; +} + +/* 结果状态 */ +.result-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 60rpx 30rpx; + text-align: center; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.result-icon { + width: 120rpx; + height: 120rpx; + border-radius: 50%; + margin: 0 auto 30rpx; + display: flex; + align-items: center; + justify-content: center; + font-size: 60rpx; + font-weight: bold; +} + +.result-icon.success { + background: #f6ffed; + color: #52c41a; + border: 4rpx solid #b7eb8f; +} + +.result-icon.error { + background: #fff2f0; + color: #ff4d4f; + border: 4rpx solid #ffccc7; +} + +.icon-text { + font-size: 60rpx; +} + +.result-title { + font-size: 36rpx; + font-weight: bold; + color: #333; + margin-bottom: 15rpx; +} + +.result-desc { + font-size: 26rpx; + color: #666; + line-height: 1.5; +} + +/* 申请信息 */ +.info-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.section-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 25rpx; + padding-bottom: 15rpx; + border-bottom: 2rpx solid #f0f0f0; +} + +.info-card { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.info-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 15rpx 0; + border-bottom: 1rpx solid #f5f5f5; +} + +.info-item:last-child { + border-bottom: none; +} + +.info-label { + font-size: 26rpx; + color: #666; +} + +.info-value { + font-size: 26rpx; + color: #333; + font-weight: 500; +} + +/* 下一步操作 */ +.action-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.action-list { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.action-item { + display: flex; + align-items: center; + padding: 20rpx; + background: #f8f9fa; + border-radius: 12rpx; + transition: all 0.3s; +} + +.action-item:active { + background: #e6f7ff; + transform: scale(0.98); +} + +.action-icon { + font-size: 40rpx; + margin-right: 20rpx; +} + +.action-content { + flex: 1; +} + +.action-title { + font-size: 28rpx; + font-weight: bold; + color: #333; + margin-bottom: 5rpx; + display: block; +} + +.action-desc { + font-size: 24rpx; + color: #666; +} + +.action-arrow { + font-size: 24rpx; + color: #999; +} + +/* 温馨提示 */ +.tips-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.tips-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 25rpx; + padding-bottom: 15rpx; + border-bottom: 2rpx solid #f0f0f0; +} + +.tips-list { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.tip-item { + display: flex; + align-items: flex-start; + font-size: 24rpx; + color: #666; + line-height: 1.5; +} + +.tip-icon { + font-size: 24rpx; + margin-right: 15rpx; + margin-top: 2rpx; +} + +.tip-text { + flex: 1; +} + +/* 底部操作栏 */ +.bottom-actions { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: white; + padding: 20rpx 30rpx; + border-top: 1rpx solid #e8e8e8; + display: flex; + gap: 20rpx; + z-index: 100; +} + +.action-btn { + flex: 1; + height: 80rpx; + border-radius: 40rpx; + font-size: 28rpx; + font-weight: bold; + border: none; + transition: all 0.3s; +} + +.action-btn.primary { + background: #1890ff; + color: white; +} + +.action-btn.secondary { + background: #f0f0f0; + color: #666; +} + +.action-btn::after { + border: none; +} + +.action-btn:active { + transform: scale(0.95); +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .result-section, + .info-section, + .action-section, + .tips-section { + margin: 15rpx; + padding: 20rpx; + } + + .bottom-actions { + padding: 15rpx 20rpx; + } +} + +/* 动画效果 */ +.result-icon { + animation: bounceIn 0.6s ease-out; +} + +@keyframes bounceIn { + 0% { + transform: scale(0.3); + opacity: 0; + } + 50% { + transform: scale(1.05); + } + 70% { + transform: scale(0.9); + } + 100% { + transform: scale(1); + opacity: 1; + } +} + +.action-item { + transition: all 0.3s ease; +} + +.action-item:hover { + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); +} \ No newline at end of file diff --git a/insurance_mini_program/pages/application/application.js b/insurance_mini_program/pages/application/application.js new file mode 100644 index 0000000..fe784bd --- /dev/null +++ b/insurance_mini_program/pages/application/application.js @@ -0,0 +1,384 @@ +// pages/application/application.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 产品ID + productId: '', + + // 产品信息 + productInfo: {}, + + // 表单数据 + formData: { + insuredName: '', + idCard: '', + phone: '', + gender: '', + birthDate: '', + beneficiaryRelationIndex: 0, + beneficiaryName: '', + coverageAmount: 10, + paymentMethod: 'annual', + healthAnswers: [] + }, + + // 受益人关系选项 + beneficiaryRelations: [ + '本人', + '配偶', + '子女', + '父母', + '兄弟姐妹', + '其他' + ], + + // 保险金额选项 + coverageAmounts: [10, 20, 30, 50, 100], + + // 健康告知问题 + healthQuestions: [ + { + question: '您是否患有或曾经患有恶性肿瘤、白血病、淋巴瘤等恶性疾病?' + }, + { + question: '您是否患有或曾经患有心脏病、心肌梗塞、冠心病、高血压等心血管疾病?' + }, + { + question: '您是否患有或曾经患有糖尿病、甲状腺疾病、肾病等内分泌或代谢疾病?' + }, + { + question: '您是否患有或曾经患有肝炎、肝硬化、肝癌等肝脏疾病?' + }, + { + question: '您是否患有或曾经患有精神疾病、癫痫、帕金森病等神经系统疾病?' + } + ], + + // 计算出的保费 + calculatedPremium: 0, + + // 是否同意协议 + agreeTerms: false, + + // 是否可以提交 + canSubmit: false, + + // 加载状态 + loading: false + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('投保申请页加载', options) + const { productId } = options + if (productId) { + this.setData({ productId }) + this.loadProductInfo(productId) + } else { + wx.showToast({ + title: '产品ID不能为空', + icon: 'none' + }) + setTimeout(() => { + wx.navigateBack() + }, 1500) + } + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('投保申请页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('投保申请页显示') + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('投保申请页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('投保申请页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.loadProductInfo(this.data.productId) + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保险投保申请', + path: `/pages/application/application?productId=${this.data.productId}`, + imageUrl: '/static/images/share-application.jpg' + } + }, + + /** + * 加载产品信息 + */ + loadProductInfo(productId) { + console.log('加载产品信息:', productId) + + // 模拟产品信息 + const mockProduct = { + id: productId, + name: '综合意外伤害保险', + subtitle: '全面保障,安心出行', + image: '/static/images/product-1.jpg', + minPremium: 99, + insurancePeriod: '1年' + } + + this.setData({ productInfo: mockProduct }) + this.calculatePremium() + }, + + /** + * 被保险人姓名输入 + */ + onInsuredNameInput(e) { + this.setData({ + 'formData.insuredName': e.detail.value + }) + this.validateForm() + }, + + /** + * 身份证号输入 + */ + onIdCardInput(e) { + this.setData({ + 'formData.idCard': e.detail.value + }) + this.validateForm() + }, + + /** + * 手机号输入 + */ + onPhoneInput(e) { + this.setData({ + 'formData.phone': e.detail.value + }) + this.validateForm() + }, + + /** + * 选择性别 + */ + selectGender(e) { + const gender = e.currentTarget.dataset.gender + this.setData({ + 'formData.gender': gender + }) + this.validateForm() + }, + + /** + * 出生日期选择 + */ + onBirthDateChange(e) { + this.setData({ + 'formData.birthDate': e.detail.value + }) + this.validateForm() + }, + + /** + * 受益人关系选择 + */ + onBeneficiaryRelationChange(e) { + this.setData({ + 'formData.beneficiaryRelationIndex': e.detail.value + }) + }, + + /** + * 受益人姓名输入 + */ + onBeneficiaryNameInput(e) { + this.setData({ + 'formData.beneficiaryName': e.detail.value + }) + }, + + /** + * 选择保险金额 + */ + selectCoverageAmount(e) { + const amount = parseInt(e.currentTarget.dataset.amount) + this.setData({ + 'formData.coverageAmount': amount + }) + this.calculatePremium() + }, + + /** + * 选择缴费方式 + */ + selectPaymentMethod(e) { + const method = e.currentTarget.dataset.method + this.setData({ + 'formData.paymentMethod': method + }) + this.calculatePremium() + }, + + /** + * 选择健康告知答案 + */ + selectHealthAnswer(e) { + const { index, answer } = e.currentTarget.dataset + const healthAnswers = [...this.data.formData.healthAnswers] + healthAnswers[index] = answer + + this.setData({ + 'formData.healthAnswers': healthAnswers + }) + this.validateForm() + }, + + /** + * 协议同意状态改变 + */ + onAgreeTermsChange(e) { + this.setData({ + agreeTerms: e.detail.value + }) + this.validateForm() + }, + + /** + * 计算保费 + */ + calculatePremium() { + const { coverageAmount, paymentMethod } = this.data.formData + const { minPremium } = this.data.productInfo + + // 简单的保费计算逻辑 + let basePremium = minPremium * (coverageAmount / 10) + if (paymentMethod === 'monthly') { + basePremium = basePremium / 12 + } + + this.setData({ + calculatedPremium: Math.round(basePremium) + }) + }, + + /** + * 验证表单 + */ + validateForm() { + const { formData } = this.data + const { agreeTerms } = this.data + + // 验证必填字段 + const requiredFields = [ + formData.insuredName, + formData.idCard, + formData.phone, + formData.gender, + formData.birthDate + ] + + const isFormValid = requiredFields.every(field => field && field.trim() !== '') + + // 验证健康告知是否全部回答 + const healthAnswersComplete = this.data.healthQuestions.length === formData.healthAnswers.length && + formData.healthAnswers.every(answer => answer !== undefined && answer !== '') + + // 验证身份证号格式 + const idCardValid = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(formData.idCard) + + // 验证手机号格式 + const phoneValid = /^1[3-9]\d{9}$/.test(formData.phone) + + const canSubmit = isFormValid && healthAnswersComplete && idCardValid && phoneValid && agreeTerms + + this.setData({ canSubmit }) + }, + + /** + * 提交投保申请 + */ + submitApplication() { + const { canSubmit, loading } = this.data + + if (!canSubmit || loading) return + + this.setData({ loading: true }) + + console.log('提交投保申请:', this.data.formData) + + // 模拟提交申请 + setTimeout(() => { + this.setData({ loading: false }) + + wx.showToast({ + title: '申请提交成功', + icon: 'success' + }) + + // 跳转到申请结果页面 + setTimeout(() => { + wx.redirectTo({ + url: `/pages/application-result/application-result?productId=${this.data.productId}&status=success` + }) + }, 1500) + + }, 2000) + }, + + /** + * 跳转到条款页面 + */ + goToTerms() { + console.log('跳转到条款页面') + wx.navigateTo({ + url: '/pages/terms/terms' + }) + }, + + /** + * 跳转到隐私政策页面 + */ + goToPrivacy() { + console.log('跳转到隐私政策页面') + wx.navigateTo({ + url: '/pages/privacy/privacy' + }) + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/application/application.json b/insurance_mini_program/pages/application/application.json new file mode 100644 index 0000000..d176dc4 --- /dev/null +++ b/insurance_mini_program/pages/application/application.json @@ -0,0 +1,7 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "投保申请", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5" +} \ No newline at end of file diff --git a/insurance_mini_program/pages/application/application.wxml b/insurance_mini_program/pages/application/application.wxml new file mode 100644 index 0000000..a7f337a --- /dev/null +++ b/insurance_mini_program/pages/application/application.wxml @@ -0,0 +1,259 @@ + + + + + + + + {{productInfo.name}} + {{productInfo.subtitle}} + + ¥{{productInfo.minPremium}} + + + + + + + + + 投保信息 + + + + 被保险人信息 + + + 姓名 + + + + + 身份证号 + + + + + 手机号 + + + + + 性别 + + + {{formData.gender === 'male' ? '●' : '○'}} + + + + {{formData.gender === 'female' ? '●' : '○'}} + + + + + + + 出生日期 + + {{formData.birthDate || '请选择出生日期'}} + + + + + + + 受益人信息 + + + 受益人关系 + + {{beneficiaryRelations[formData.beneficiaryRelationIndex] || '请选择关系'}} + + + + + 受益人姓名 + + + + + + + 保险信息 + + + 保险金额 + + + ¥{{item}}万 + + + + + + 缴费方式 + + + {{formData.paymentMethod === 'annual' ? '●' : '○'}} + 年缴 + + + {{formData.paymentMethod === 'monthly' ? '●' : '○'}} + 月缴 + + + + + + 保险期间 + + {{productInfo.insurancePeriod || '1年'}} + + + + + + + 健康告知 + + 请如实回答以下问题,如有隐瞒可能影响理赔 + + + + + {{item.question}} + + + {{formData.healthAnswers[index] === 'yes' ? '●' : '○'}} + + + + {{formData.healthAnswers[index] === 'no' ? '●' : '○'}} + + + + + + + + + + + 保费计算 + + + 保险金额: + ¥{{formData.coverageAmount}}万 + + + 缴费方式: + {{formData.paymentMethod === 'annual' ? '年缴' : '月缴'}} + + + 应缴保费: + ¥{{calculatedPremium}} + + + + + + + + + + + + 我已阅读并同意 + 《保险条款》 + 和 + 《隐私政策》 + + + + + + + + + + + + + + + 处理中... + + \ No newline at end of file diff --git a/insurance_mini_program/pages/application/application.wxss b/insurance_mini_program/pages/application/application.wxss new file mode 100644 index 0000000..fc74326 --- /dev/null +++ b/insurance_mini_program/pages/application/application.wxss @@ -0,0 +1,454 @@ +/* pages/application/application.wxss */ +.container { + background: #f5f5f5; + min-height: 100vh; + padding-bottom: 120rpx; +} + +/* 产品信息卡片 */ +.product-card { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.product-info { + display: flex; + align-items: center; + gap: 20rpx; +} + +.product-img { + width: 120rpx; + height: 120rpx; + border-radius: 12rpx; +} + +.product-details { + flex: 1; +} + +.product-name { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; + display: block; +} + +.product-desc { + font-size: 24rpx; + color: #666; + margin-bottom: 15rpx; + display: block; +} + +.price-info { + display: flex; + align-items: baseline; +} + +.price { + font-size: 36rpx; + font-weight: bold; + color: #ff4757; +} + +.price-unit { + font-size: 24rpx; + color: #999; + margin-left: 5rpx; +} + +/* 表单区域 */ +.form-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.section-title { + font-size: 36rpx; + font-weight: bold; + color: #333; + margin-bottom: 30rpx; + padding-bottom: 15rpx; + border-bottom: 2rpx solid #f0f0f0; +} + +.form-group { + margin-bottom: 40rpx; +} + +.group-title { + font-size: 28rpx; + font-weight: bold; + color: #333; + margin-bottom: 25rpx; + padding-left: 15rpx; + border-left: 4rpx solid #1890ff; +} + +.form-item { + margin-bottom: 25rpx; +} + +.label { + font-size: 26rpx; + color: #333; + margin-bottom: 10rpx; + display: block; +} + +.label.required::after { + content: '*'; + color: #ff4757; + margin-left: 5rpx; +} + +.form-input { + width: 100%; + height: 80rpx; + background: #f8f9fa; + border-radius: 12rpx; + padding: 0 20rpx; + font-size: 28rpx; + color: #333; + border: 2rpx solid transparent; + transition: all 0.3s; +} + +.form-input:focus { + border-color: #1890ff; + background: white; +} + +/* 单选按钮组 */ +.radio-group { + display: flex; + gap: 30rpx; +} + +.radio-item { + display: flex; + align-items: center; + padding: 15rpx 25rpx; + background: #f8f9fa; + border-radius: 25rpx; + border: 2rpx solid transparent; + transition: all 0.3s; +} + +.radio-item.active { + background: #e6f7ff; + border-color: #1890ff; +} + +.radio-icon { + font-size: 24rpx; + color: #1890ff; + margin-right: 10rpx; +} + +.radio-text { + font-size: 26rpx; + color: #333; +} + +/* 选择器 */ +.picker, .date-picker { + width: 100%; + height: 80rpx; + background: #f8f9fa; + border-radius: 12rpx; + padding: 0 20rpx; + display: flex; + align-items: center; + border: 2rpx solid transparent; + transition: all 0.3s; +} + +.picker:active, .date-picker:active { + border-color: #1890ff; + background: white; +} + +.picker-text { + font-size: 28rpx; + color: #333; +} + +/* 保险金额选择器 */ +.amount-selector { + display: flex; + flex-wrap: wrap; + gap: 15rpx; +} + +.amount-option { + padding: 15rpx 25rpx; + background: #f8f9fa; + border-radius: 25rpx; + border: 2rpx solid transparent; + transition: all 0.3s; +} + +.amount-option.active { + background: #e6f7ff; + border-color: #1890ff; +} + +.amount-text { + font-size: 26rpx; + color: #333; +} + +/* 健康告知 */ +.health-notice { + background: #fff7e6; + padding: 20rpx; + border-radius: 12rpx; + margin-bottom: 25rpx; + border-left: 4rpx solid #faad14; +} + +.notice-text { + font-size: 24rpx; + color: #d48806; + line-height: 1.5; +} + +.health-questions { + display: flex; + flex-direction: column; + gap: 25rpx; +} + +.question-item { + padding: 25rpx; + background: #f8f9fa; + border-radius: 12rpx; +} + +.question-text { + font-size: 26rpx; + color: #333; + margin-bottom: 15rpx; + display: block; + line-height: 1.5; +} + +.answer-options { + display: flex; + gap: 20rpx; +} + +.option-item { + display: flex; + align-items: center; + padding: 10rpx 20rpx; + background: white; + border-radius: 20rpx; + border: 2rpx solid #e8e8e8; + transition: all 0.3s; +} + +.option-item.active { + background: #e6f7ff; + border-color: #1890ff; +} + +.option-icon { + font-size: 20rpx; + color: #1890ff; + margin-right: 8rpx; +} + +.option-text { + font-size: 24rpx; + color: #333; +} + +/* 保费计算 */ +.premium-section { + margin-top: 30rpx; +} + +.premium-card { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border-radius: 16rpx; + padding: 30rpx; + color: white; +} + +.premium-title { + font-size: 32rpx; + font-weight: bold; + margin-bottom: 20rpx; + text-align: center; +} + +.premium-details { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.premium-item { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 26rpx; +} + +.premium-item.total { + font-size: 32rpx; + font-weight: bold; + padding-top: 15rpx; + border-top: 1rpx solid rgba(255, 255, 255, 0.3); +} + +.premium-label { + color: rgba(255, 255, 255, 0.9); +} + +.premium-value { + color: white; + font-weight: bold; +} + +/* 协议确认 */ +.agreement-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.agreement-item { + display: flex; + align-items: flex-start; + font-size: 24rpx; + color: #666; + line-height: 1.5; +} + +.agreement-text { + margin-left: 15rpx; + flex: 1; +} + +.link { + color: #1890ff; +} + +/* 底部操作栏 */ +.bottom-actions { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: white; + padding: 20rpx 30rpx; + border-top: 1rpx solid #e8e8e8; + z-index: 100; +} + +.submit-btn { + width: 100%; + height: 80rpx; + border-radius: 40rpx; + font-size: 32rpx; + font-weight: bold; + border: none; + transition: all 0.3s; +} + +.submit-btn.active { + background: #1890ff; + color: white; +} + +.submit-btn.disabled { + background: #f0f0f0; + color: #ccc; +} + +.submit-btn::after { + border: none; +} + +/* 加载状态 */ +.loading-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.loading-content { + background: white; + padding: 40rpx; + border-radius: 16rpx; + display: flex; + flex-direction: column; + align-items: center; + gap: 20rpx; +} + +.loading-spinner { + width: 60rpx; + height: 60rpx; + border: 4rpx solid #f0f0f0; + border-top: 4rpx solid #1890ff; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading-text { + font-size: 28rpx; + color: #666; +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .product-card, + .form-section, + .agreement-section { + margin: 15rpx; + padding: 20rpx; + } + + .bottom-actions { + padding: 15rpx 20rpx; + } +} + +/* 动画效果 */ +.radio-item, +.amount-option, +.option-item { + transition: all 0.3s ease; +} + +.radio-item:active, +.amount-option:active, +.option-item:active { + transform: scale(0.95); +} \ No newline at end of file diff --git a/insurance_mini_program/pages/claim-detail/claim-detail.js b/insurance_mini_program/pages/claim-detail/claim-detail.js new file mode 100644 index 0000000..5a909c9 --- /dev/null +++ b/insurance_mini_program/pages/claim-detail/claim-detail.js @@ -0,0 +1,339 @@ +// pages/claim-detail/claim-detail.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 理赔ID + claimId: '', + + // 理赔信息 + claimInfo: {} + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('理赔详情页加载', options) + const { id } = options + if (id) { + this.setData({ claimId: id }) + this.loadClaimDetail(id) + } else { + wx.showToast({ + title: '理赔ID不能为空', + icon: 'none' + }) + setTimeout(() => { + wx.navigateBack() + }, 1500) + } + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('理赔详情页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('理赔详情页显示') + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('理赔详情页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('理赔详情页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.loadClaimDetail(this.data.claimId) + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '理赔详情', + path: `/pages/claim-detail/claim-detail?id=${this.data.claimId}`, + imageUrl: '/static/images/share-claim-detail.jpg' + } + }, + + /** + * 加载理赔详情 + */ + loadClaimDetail(claimId) { + console.log('加载理赔详情:', claimId) + + // 模拟理赔详情数据 + const mockClaimInfo = this.getMockClaimDetail(claimId) + this.setData({ claimInfo: mockClaimInfo }) + }, + + /** + * 获取模拟理赔详情数据 + */ + getMockClaimDetail(claimId) { + const mockClaims = { + '1': { + id: '1', + claimNo: 'CLM20240115001', + claimType: '意外伤害理赔', + status: 'pending', + statusIcon: '⏳', + statusText: '待处理', + statusDesc: '您的理赔申请已提交,正在等待审核', + applicationTime: '2024-01-15 14:30', + claimAmount: 5000, + policyNo: 'POL20240115001', + insuredName: '张先生', + currentStep: 1, + progressSteps: [ + { + title: '申请提交', + desc: '理赔申请已成功提交', + time: '2024-01-15 14:30' + }, + { + title: '材料审核', + desc: '正在审核相关材料', + time: '' + }, + { + title: '现场查勘', + desc: '安排现场查勘', + time: '' + }, + { + title: '理赔决定', + desc: '做出理赔决定', + time: '' + }, + { + title: '赔款支付', + desc: '完成赔款支付', + time: '' + } + ], + accidentDesc: '在上班途中发生交通事故,导致右腿骨折', + accidentTime: '2024-01-15 08:30', + accidentLocation: '北京市朝阳区建国路与东三环交叉口', + hospitalName: '北京协和医院', + diagnosis: '右腿胫骨骨折,需要手术治疗', + materials: [ + { + icon: '📄', + name: '理赔申请书', + status: 'uploaded', + statusText: '已上传' + }, + { + icon: '🏥', + name: '医院诊断证明', + status: 'uploaded', + statusText: '已上传' + }, + { + icon: '💰', + name: '医疗费用发票', + status: 'pending', + statusText: '待上传' + }, + { + icon: '📋', + name: '事故证明', + status: 'uploaded', + statusText: '已上传' + } + ], + records: [ + { + time: '2024-01-15 14:30', + title: '申请提交', + desc: '用户提交理赔申请', + operator: '张先生' + }, + { + time: '2024-01-15 15:00', + title: '申请确认', + desc: '系统确认收到申请', + operator: '系统' + } + ] + }, + '2': { + id: '2', + claimNo: 'CLM20240110002', + claimType: '医疗费用理赔', + status: 'processing', + statusIcon: '🔄', + statusText: '处理中', + statusDesc: '您的理赔申请正在处理中,预计3-5个工作日完成', + applicationTime: '2024-01-10 09:15', + claimAmount: 12000, + policyNo: 'POL20240110002', + insuredName: '李女士', + currentStep: 3, + progressSteps: [ + { + title: '申请提交', + desc: '理赔申请已成功提交', + time: '2024-01-10 09:15' + }, + { + title: '材料审核', + desc: '材料审核已完成', + time: '2024-01-11 10:30' + }, + { + title: '现场查勘', + desc: '正在安排现场查勘', + time: '' + }, + { + title: '理赔决定', + desc: '做出理赔决定', + time: '' + }, + { + title: '赔款支付', + desc: '完成赔款支付', + time: '' + } + ], + accidentDesc: '因急性阑尾炎住院治疗', + accidentTime: '2024-01-08 20:00', + accidentLocation: '家中', + hospitalName: '北京友谊医院', + diagnosis: '急性阑尾炎,已进行阑尾切除手术', + materials: [ + { + icon: '📄', + name: '理赔申请书', + status: 'uploaded', + statusText: '已上传' + }, + { + icon: '🏥', + name: '医院诊断证明', + status: 'uploaded', + statusText: '已上传' + }, + { + icon: '💰', + name: '医疗费用发票', + status: 'uploaded', + statusText: '已上传' + }, + { + icon: '📋', + name: '住院病历', + status: 'uploaded', + statusText: '已上传' + } + ], + records: [ + { + time: '2024-01-10 09:15', + title: '申请提交', + desc: '用户提交理赔申请', + operator: '李女士' + }, + { + time: '2024-01-10 10:00', + title: '申请确认', + desc: '系统确认收到申请', + operator: '系统' + }, + { + time: '2024-01-11 10:30', + title: '材料审核', + desc: '材料审核通过', + operator: '审核员' + } + ] + } + } + + return mockClaims[claimId] || mockClaims['1'] + }, + + /** + * 预览材料 + */ + previewMaterial(e) { + const index = e.currentTarget.dataset.index + const material = this.data.claimInfo.materials[index] + console.log('预览材料:', material.name) + + wx.showToast({ + title: '材料预览功能开发中', + icon: 'none' + }) + }, + + /** + * 联系客服 + */ + contactService() { + console.log('联系客服') + wx.showModal({ + title: '联系客服', + content: '客服电话:400-123-4567\n工作时间:9:00-18:00', + confirmText: '拨打电话', + success: (res) => { + if (res.confirm) { + wx.makePhoneCall({ + phoneNumber: '400-123-4567' + }) + } + } + }) + }, + + /** + * 提交补充材料 + */ + submitSupplement() { + console.log('提交补充材料') + wx.navigateTo({ + url: '/pages/supplement-materials/supplement-materials?claimId=' + this.data.claimId + }) + }, + + /** + * 返回上一页 + */ + goBack() { + console.log('返回上一页') + wx.navigateBack() + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/claim-detail/claim-detail.json b/insurance_mini_program/pages/claim-detail/claim-detail.json new file mode 100644 index 0000000..0ff04f6 --- /dev/null +++ b/insurance_mini_program/pages/claim-detail/claim-detail.json @@ -0,0 +1,7 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "理赔详情", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5" +} \ No newline at end of file diff --git a/insurance_mini_program/pages/claim-detail/claim-detail.wxml b/insurance_mini_program/pages/claim-detail/claim-detail.wxml new file mode 100644 index 0000000..f2bf81d --- /dev/null +++ b/insurance_mini_program/pages/claim-detail/claim-detail.wxml @@ -0,0 +1,170 @@ + + + + + + {{claimInfo.statusIcon}} + + + {{claimInfo.statusText}} + {{claimInfo.statusDesc}} + + + + + + 理赔信息 + + + + 理赔单号 + {{claimInfo.claimNo}} + + + + 理赔类型 + {{claimInfo.claimType}} + + + + 申请时间 + {{claimInfo.applicationTime}} + + + + 理赔金额 + ¥{{claimInfo.claimAmount}} + + + + 保单号 + {{claimInfo.policyNo}} + + + + 被保险人 + {{claimInfo.insuredName}} + + + + + + + 理赔进度 + + + + + {{index < claimInfo.currentStep ? '✓' : (index + 1)}} + + + {{item.title}} + {{item.desc}} + {{item.time}} + + + + + + + + 理赔详情 + + + + 事故描述 + {{claimInfo.accidentDesc}} + + + + 事故发生时间 + {{claimInfo.accidentTime}} + + + + 事故发生地点 + {{claimInfo.accidentLocation}} + + + + 医院名称 + {{claimInfo.hospitalName}} + + + + 诊断结果 + {{claimInfo.diagnosis}} + + + + + + + 相关材料 + + + + {{item.icon}} + + {{item.name}} + {{item.statusText}} + + + + + + + + + + + 处理记录 + + + + {{item.time}} + + {{item.title}} + {{item.desc}} + + {{item.operator}} + + + + + + + + + + + + + \ No newline at end of file diff --git a/insurance_mini_program/pages/claim-detail/claim-detail.wxss b/insurance_mini_program/pages/claim-detail/claim-detail.wxss new file mode 100644 index 0000000..400e42b --- /dev/null +++ b/insurance_mini_program/pages/claim-detail/claim-detail.wxss @@ -0,0 +1,414 @@ +/* pages/claim-detail/claim-detail.wxss */ +.container { + background: #f5f5f5; + min-height: 100vh; + padding-bottom: 120rpx; +} + +/* 理赔状态卡片 */ +.status-card { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 40rpx 30rpx; + display: flex; + align-items: center; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.status-icon { + width: 100rpx; + height: 100rpx; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 30rpx; + font-size: 50rpx; + font-weight: bold; +} + +.status-icon.pending { + background: #fff7e6; + color: #d48806; +} + +.status-icon.processing { + background: #e6f7ff; + color: #1890ff; +} + +.status-icon.completed { + background: #f6ffed; + color: #52c41a; +} + +.status-icon.rejected { + background: #fff2f0; + color: #ff4d4f; +} + +.icon-text { + font-size: 50rpx; +} + +.status-content { + flex: 1; +} + +.status-title { + font-size: 36rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; + display: block; +} + +.status-desc { + font-size: 24rpx; + color: #666; + line-height: 1.4; +} + +/* 信息区域 */ +.info-section, +.progress-section, +.detail-section, +.materials-section, +.records-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.section-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 25rpx; + padding-bottom: 15rpx; + border-bottom: 2rpx solid #f0f0f0; +} + +.info-card, +.detail-card { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.info-item, +.detail-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 15rpx 0; + border-bottom: 1rpx solid #f5f5f5; +} + +.info-item:last-child, +.detail-item:last-child { + border-bottom: none; +} + +.info-label, +.detail-label { + font-size: 26rpx; + color: #666; + min-width: 150rpx; +} + +.info-value, +.detail-value { + font-size: 26rpx; + color: #333; + font-weight: 500; + text-align: right; + flex: 1; +} + +.info-value.amount, +.detail-value.amount { + color: #ff4757; + font-weight: bold; + font-size: 28rpx; +} + +/* 理赔进度 */ +.progress-timeline { + position: relative; + padding-left: 40rpx; +} + +.progress-timeline::before { + content: ''; + position: absolute; + left: 20rpx; + top: 0; + bottom: 0; + width: 2rpx; + background: #e8e8e8; +} + +.timeline-item { + position: relative; + margin-bottom: 40rpx; + display: flex; + align-items: flex-start; +} + +.timeline-item:last-child { + margin-bottom: 0; +} + +.timeline-dot { + position: absolute; + left: -30rpx; + top: 0; + width: 40rpx; + height: 40rpx; + border-radius: 50%; + background: #e8e8e8; + display: flex; + align-items: center; + justify-content: center; + z-index: 1; +} + +.timeline-item.active .timeline-dot { + background: #1890ff; + color: white; +} + +.timeline-item.active .timeline-dot .dot-icon { + color: white; +} + +.dot-icon { + font-size: 20rpx; + font-weight: bold; + color: #999; +} + +.timeline-content { + flex: 1; + padding-left: 20rpx; +} + +.timeline-title { + font-size: 28rpx; + font-weight: bold; + color: #333; + margin-bottom: 8rpx; + display: block; +} + +.timeline-desc { + font-size: 24rpx; + color: #666; + margin-bottom: 5rpx; + display: block; + line-height: 1.4; +} + +.timeline-time { + font-size: 22rpx; + color: #999; +} + +/* 相关材料 */ +.materials-list { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.material-item { + display: flex; + align-items: center; + padding: 20rpx; + background: #f8f9fa; + border-radius: 12rpx; +} + +.material-icon { + font-size: 40rpx; + margin-right: 20rpx; +} + +.material-info { + flex: 1; +} + +.material-name { + font-size: 26rpx; + color: #333; + margin-bottom: 5rpx; + display: block; +} + +.material-status { + font-size: 22rpx; + padding: 4rpx 12rpx; + border-radius: 12rpx; + display: inline-block; +} + +.material-status.uploaded { + background: #f6ffed; + color: #52c41a; +} + +.material-status.pending { + background: #fff7e6; + color: #d48806; +} + +.material-status.rejected { + background: #fff2f0; + color: #ff4d4f; +} + +.material-actions { + margin-left: 20rpx; +} + +/* 处理记录 */ +.records-list { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.record-item { + display: flex; + align-items: flex-start; + padding: 20rpx; + background: #f8f9fa; + border-radius: 12rpx; +} + +.record-time { + font-size: 22rpx; + color: #999; + margin-right: 20rpx; + min-width: 120rpx; +} + +.record-content { + flex: 1; + margin-right: 20rpx; +} + +.record-title { + font-size: 26rpx; + font-weight: bold; + color: #333; + margin-bottom: 5rpx; + display: block; +} + +.record-desc { + font-size: 24rpx; + color: #666; + line-height: 1.4; +} + +.record-operator { + font-size: 22rpx; + color: #999; + min-width: 80rpx; + text-align: right; +} + +/* 底部操作栏 */ +.bottom-actions { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: white; + padding: 20rpx 30rpx; + border-top: 1rpx solid #e8e8e8; + display: flex; + gap: 20rpx; + z-index: 100; +} + +.action-btn { + flex: 1; + height: 80rpx; + border-radius: 40rpx; + font-size: 28rpx; + font-weight: bold; + border: none; + transition: all 0.3s; +} + +.action-btn.primary { + background: #1890ff; + color: white; +} + +.action-btn.secondary { + background: #f0f0f0; + color: #666; +} + +.action-btn.small { + padding: 12rpx 24rpx; + font-size: 22rpx; + border-radius: 20rpx; + min-width: 100rpx; + height: auto; +} + +.action-btn::after { + border: none; +} + +.action-btn:active { + transform: scale(0.95); +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .status-card, + .info-section, + .progress-section, + .detail-section, + .materials-section, + .records-section { + margin: 15rpx; + padding: 20rpx; + } + + .bottom-actions { + padding: 15rpx 20rpx; + } +} + +/* 动画效果 */ +.timeline-item { + transition: all 0.3s ease; +} + +.material-item { + transition: all 0.3s ease; +} + +.material-item:active { + background: #e6f7ff; + transform: scale(0.98); +} + +.record-item { + transition: all 0.3s ease; +} + +.record-item:active { + background: #e6f7ff; + transform: scale(0.98); +} \ No newline at end of file diff --git a/insurance_mini_program/pages/claims/claims.js b/insurance_mini_program/pages/claims/claims.js new file mode 100644 index 0000000..833b53e --- /dev/null +++ b/insurance_mini_program/pages/claims/claims.js @@ -0,0 +1,260 @@ +// pages/claims/claims.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 当前激活的标签 + activeTab: 'all', + + // 理赔列表 + claimsList: [], + + // 过滤后的理赔列表 + filteredClaims: [], + + // 加载状态 + loading: false, + + // 是否有更多数据 + hasMore: true, + + // 当前页码 + currentPage: 1 + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('理赔申请页加载', options) + this.loadClaimsList() + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('理赔申请页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('理赔申请页显示') + this.loadClaimsList() + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('理赔申请页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('理赔申请页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.setData({ + currentPage: 1, + hasMore: true + }) + this.loadClaimsList() + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + if (this.data.hasMore && !this.data.loading) { + this.loadMore() + } + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保险理赔申请', + path: '/pages/claims/claims', + imageUrl: '/static/images/share-claims.jpg' + } + }, + + /** + * 加载理赔列表 + */ + loadClaimsList() { + this.setData({ loading: true }) + + console.log('加载理赔列表') + + // 模拟API调用 + setTimeout(() => { + const mockClaims = this.getMockClaims() + this.setData({ + claimsList: mockClaims, + filteredClaims: this.filterClaims(mockClaims, this.data.activeTab), + loading: false + }) + }, 1000) + }, + + /** + * 获取模拟理赔数据 + */ + getMockClaims() { + return [ + { + id: '1', + title: '意外伤害理赔', + description: '交通事故导致的人身伤害', + status: 'pending', + statusText: '待处理', + applicationTime: '2024-01-15 14:30', + claimAmount: 5000, + policyNo: 'POL20240115001' + }, + { + id: '2', + title: '医疗费用理赔', + description: '住院医疗费用报销', + status: 'processing', + statusText: '处理中', + applicationTime: '2024-01-10 09:15', + claimAmount: 12000, + policyNo: 'POL20240110002' + }, + { + id: '3', + title: '重疾理赔', + description: '重大疾病保险金申请', + status: 'completed', + statusText: '已完成', + applicationTime: '2024-01-05 16:45', + claimAmount: 300000, + policyNo: 'POL20240105003' + }, + { + id: '4', + title: '意外身故理赔', + description: '意外身故保险金申请', + status: 'rejected', + statusText: '已拒绝', + applicationTime: '2024-01-01 11:20', + claimAmount: 500000, + policyNo: 'POL20240101004' + }, + { + id: '5', + title: '住院津贴理赔', + description: '住院期间津贴申请', + status: 'pending', + statusText: '待处理', + applicationTime: '2024-01-20 08:30', + claimAmount: 2000, + policyNo: 'POL20240120005' + } + ] + }, + + /** + * 过滤理赔列表 + */ + filterClaims(claims, status) { + if (status === 'all') { + return claims + } + return claims.filter(claim => claim.status === status) + }, + + /** + * 切换标签 + */ + switchTab(e) { + const tab = e.currentTarget.dataset.tab + console.log('切换标签:', tab) + + this.setData({ + activeTab: tab, + filteredClaims: this.filterClaims(this.data.claimsList, tab) + }) + }, + + /** + * 跳转到理赔详情 + */ + goToClaimDetail(e) { + const claimId = e.currentTarget.dataset.id + console.log('跳转到理赔详情:', claimId) + wx.navigateTo({ + url: `/pages/claim-detail/claim-detail?id=${claimId}` + }) + }, + + /** + * 跳转到新理赔申请 + */ + goToNewClaim() { + console.log('跳转到新理赔申请') + wx.navigateTo({ + url: '/pages/new-claim/new-claim' + }) + }, + + /** + * 加载更多 + */ + loadMore() { + if (this.data.loading || !this.data.hasMore) return + + this.setData({ loading: true }) + + console.log('加载更多理赔数据') + + // 模拟加载更多数据 + setTimeout(() => { + const newClaims = this.getMockClaims().map((claim, index) => ({ + ...claim, + id: (this.data.claimsList.length + index + 1).toString(), + applicationTime: this.formatDate(new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000)) + })) + + const updatedClaims = [...this.data.claimsList, ...newClaims] + + this.setData({ + claimsList: updatedClaims, + filteredClaims: this.filterClaims(updatedClaims, this.data.activeTab), + loading: false, + hasMore: updatedClaims.length < 20 // 模拟最多20条数据 + }) + }, 1000) + }, + + /** + * 格式化日期 + */ + formatDate(date) { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + const hours = String(date.getHours()).padStart(2, '0') + const minutes = String(date.getMinutes()).padStart(2, '0') + + return `${year}-${month}-${day} ${hours}:${minutes}` + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/claims/claims.json b/insurance_mini_program/pages/claims/claims.json new file mode 100644 index 0000000..3a670d3 --- /dev/null +++ b/insurance_mini_program/pages/claims/claims.json @@ -0,0 +1,8 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "理赔申请", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5", + "onReachBottomDistance": 50 +} \ No newline at end of file diff --git a/insurance_mini_program/pages/claims/claims.wxml b/insurance_mini_program/pages/claims/claims.wxml new file mode 100644 index 0000000..df79825 --- /dev/null +++ b/insurance_mini_program/pages/claims/claims.wxml @@ -0,0 +1,120 @@ + + + + + + 理赔申请 + 快速申请理赔,专业服务保障 + + + + + + + + + + 全部 + + + 待处理 + + + 处理中 + + + 已完成 + + + + + + + + + {{item.title}} + {{item.description}} + + + {{item.statusText}} + + + + + + 申请时间: + {{item.applicationTime}} + + + 理赔金额: + ¥{{item.claimAmount}} + + + 保单号: + {{item.policyNo}} + + + + + + + + + + + + + 📋 + 暂无理赔记录 + 您还没有任何理赔申请记录 + + + + + + 加载中... + 加载更多 + + \ No newline at end of file diff --git a/insurance_mini_program/pages/claims/claims.wxss b/insurance_mini_program/pages/claims/claims.wxss new file mode 100644 index 0000000..66e3d88 --- /dev/null +++ b/insurance_mini_program/pages/claims/claims.wxss @@ -0,0 +1,342 @@ +/* pages/claims/claims.wxss */ +.container { + background: #f5f5f5; + min-height: 100vh; +} + +/* 页面头部 */ +.header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + padding: 30rpx; + display: flex; + justify-content: space-between; + align-items: center; + color: white; +} + +.header-content { + flex: 1; +} + +.header-title { + font-size: 36rpx; + font-weight: bold; + margin-bottom: 10rpx; + display: block; +} + +.header-desc { + font-size: 24rpx; + opacity: 0.9; + display: block; +} + +.header-actions { + margin-left: 20rpx; +} + +.action-btn { + display: flex; + align-items: center; + padding: 15rpx 25rpx; + background: rgba(255, 255, 255, 0.2); + border: 2rpx solid rgba(255, 255, 255, 0.3); + border-radius: 25rpx; + color: white; + font-size: 24rpx; + transition: all 0.3s; +} + +.action-btn::after { + border: none; +} + +.action-btn:active { + background: rgba(255, 255, 255, 0.3); + transform: scale(0.95); +} + +.btn-icon { + font-size: 28rpx; + margin-right: 8rpx; +} + +.btn-text { + font-size: 24rpx; +} + +/* 筛选标签 */ +.filter-tabs { + background: white; + display: flex; + padding: 0 30rpx; + border-bottom: 1rpx solid #e8e8e8; +} + +.tab-item { + flex: 1; + text-align: center; + padding: 30rpx 0; + font-size: 28rpx; + color: #666; + position: relative; + transition: all 0.3s; +} + +.tab-item.active { + color: #1890ff; + font-weight: bold; +} + +.tab-item.active::after { + content: ''; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 60rpx; + height: 4rpx; + background: #1890ff; + border-radius: 2rpx; +} + +/* 理赔列表 */ +.claims-list { + padding: 20rpx; +} + +.claim-item { + background: white; + border-radius: 16rpx; + padding: 30rpx; + margin-bottom: 20rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); + transition: all 0.3s; +} + +.claim-item:active { + transform: scale(0.98); + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15); +} + +.claim-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 20rpx; +} + +.claim-info { + flex: 1; +} + +.claim-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 8rpx; + display: block; +} + +.claim-desc { + font-size: 24rpx; + color: #666; + line-height: 1.4; +} + +.claim-status { + padding: 8rpx 16rpx; + border-radius: 20rpx; + font-size: 22rpx; + font-weight: bold; +} + +.claim-status.pending { + background: #fff7e6; + color: #d48806; +} + +.claim-status.processing { + background: #e6f7ff; + color: #1890ff; +} + +.claim-status.completed { + background: #f6ffed; + color: #52c41a; +} + +.claim-status.rejected { + background: #fff2f0; + color: #ff4d4f; +} + +.status-text { + font-size: 22rpx; +} + +/* 理赔详情 */ +.claim-details { + margin-bottom: 25rpx; +} + +.detail-item { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10rpx; + font-size: 24rpx; +} + +.detail-item:last-child { + margin-bottom: 0; +} + +.detail-label { + color: #666; +} + +.detail-value { + color: #333; + font-weight: 500; +} + +.detail-value.amount { + color: #ff4757; + font-weight: bold; + font-size: 26rpx; +} + +/* 理赔操作 */ +.claim-actions { + display: flex; + gap: 15rpx; + justify-content: flex-end; +} + +.action-btn.small { + padding: 12rpx 24rpx; + font-size: 22rpx; + border-radius: 20rpx; + min-width: 120rpx; +} + +.action-btn.small.primary { + background: #1890ff; + color: white; + border: none; +} + +.action-btn.small:not(.primary) { + background: #f0f0f0; + color: #666; + border: none; +} + +.action-btn.small::after { + border: none; +} + +.action-btn.small:active { + transform: scale(0.95); +} + +/* 空状态 */ +.empty-state { + text-align: center; + padding: 100rpx 40rpx; +} + +.empty-icon { + font-size: 120rpx; + margin-bottom: 30rpx; + opacity: 0.5; +} + +.empty-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 15rpx; + display: block; +} + +.empty-desc { + font-size: 26rpx; + color: #666; + margin-bottom: 40rpx; + display: block; +} + +.empty-btn { + background: #1890ff; + color: white; + border: none; + border-radius: 25rpx; + padding: 20rpx 40rpx; + font-size: 28rpx; + font-weight: bold; +} + +.empty-btn::after { + border: none; +} + +.empty-btn:active { + transform: scale(0.95); +} + +/* 加载更多 */ +.load-more { + text-align: center; + padding: 30rpx; +} + +.loading-text { + font-size: 24rpx; + color: #666; +} + +.load-more-btn { + font-size: 26rpx; + color: #1890ff; + padding: 15rpx 30rpx; + background: white; + border-radius: 25rpx; + display: inline-block; + border: 2rpx solid #1890ff; + transition: all 0.3s; +} + +.load-more-btn:active { + background: #e6f7ff; + transform: scale(0.95); +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .header { + padding: 20rpx; + } + + .claims-list { + padding: 15rpx; + } + + .claim-item { + padding: 20rpx; + } +} + +/* 动画效果 */ +.claim-item { + transition: all 0.3s ease; +} + +.tab-item { + transition: all 0.3s ease; +} + +.action-btn { + transition: all 0.3s ease; +} \ No newline at end of file diff --git a/insurance_mini_program/pages/index/index.js b/insurance_mini_program/pages/index/index.js new file mode 100644 index 0000000..5948d72 --- /dev/null +++ b/insurance_mini_program/pages/index/index.js @@ -0,0 +1,213 @@ +// pages/index/index.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 热门产品数据 + hotProducts: [ + { + id: 1, + name: '综合意外险', + description: '全面保障意外伤害,保费低廉', + min_premium: 99, + icon: '🛡️' + }, + { + id: 2, + name: '重疾保险', + description: '重大疾病保障,安心无忧', + min_premium: 299, + icon: '🏥' + }, + { + id: 3, + name: '车险', + description: '车辆全面保障,理赔快速', + min_premium: 1999, + icon: '🚗' + }, + { + id: 4, + name: '旅行险', + description: '出行安全保障,全球覆盖', + min_premium: 59, + icon: '✈️' + } + ], + + // 新闻资讯数据 + newsList: [ + { + id: 1, + title: '2024年保险新政策解读', + summary: '了解最新的保险政策变化,为您的保障规划提供参考', + date: '2024-01-15' + }, + { + id: 2, + title: '如何选择适合自己的保险产品', + summary: '专业指导帮助您选择最合适的保险方案', + date: '2024-01-12' + }, + { + id: 3, + title: '理赔流程优化,服务更便捷', + summary: '我们持续优化理赔流程,让您的理赔更加便捷快速', + date: '2024-01-10' + } + ] + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('首页加载完成') + this.loadPageData() + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('首页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('首页显示') + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('首页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('首页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.loadPageData() + // 停止下拉刷新 + setTimeout(() => { + wx.stopPullDownRefresh() + }, 1000) + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + // 可以在这里加载更多数据 + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保险服务 - 专业安全的保险平台', + path: '/pages/index/index', + imageUrl: '/static/images/share-cover.jpg' + } + }, + + /** + * 加载页面数据 + */ + loadPageData() { + console.log('加载首页数据') + // 这里可以调用API获取数据 + // 目前使用模拟数据 + }, + + /** + * 跳转到产品详情页 + */ + goToProductDetail(e) { + const productId = e.currentTarget.dataset.id + console.log('跳转到产品详情页:', productId) + wx.navigateTo({ + url: `/pages/product-detail/product-detail?id=${productId}` + }) + }, + + /** + * 跳转到产品列表页 + */ + goToProducts() { + console.log('跳转到产品列表页') + wx.switchTab({ + url: '/pages/products/products' + }) + }, + + /** + * 跳转到我的页面 + */ + goToMy() { + console.log('跳转到我的页面') + wx.switchTab({ + url: '/pages/my/my' + }) + }, + + /** + * 跳转到理赔申请页 + */ + goToClaims() { + console.log('跳转到理赔申请页') + wx.navigateTo({ + url: '/pages/claims/claims' + }) + }, + + /** + * 显示客服服务 + */ + goToService() { + console.log('显示客服服务') + wx.showModal({ + title: '客服服务', + content: '客服电话:400-888-8888\n服务时间:周一至周日 9:00-18:00', + showCancel: false, + confirmText: '知道了' + }) + }, + + /** + * 跳转到新闻列表页 + */ + goToNews() { + console.log('跳转到新闻列表页') + wx.navigateTo({ + url: '/pages/news/news' + }) + }, + + /** + * 跳转到新闻详情页 + */ + goToNewsDetail(e) { + const newsId = e.currentTarget.dataset.id + console.log('跳转到新闻详情页:', newsId) + wx.navigateTo({ + url: `/pages/news-detail/news-detail?id=${newsId}` + }) + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/index/index.json b/insurance_mini_program/pages/index/index.json new file mode 100644 index 0000000..7474754 --- /dev/null +++ b/insurance_mini_program/pages/index/index.json @@ -0,0 +1,7 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "保险服务", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5" +} \ No newline at end of file diff --git a/insurance_mini_program/pages/index/index.wxml b/insurance_mini_program/pages/index/index.wxml new file mode 100644 index 0000000..a08ed1b --- /dev/null +++ b/insurance_mini_program/pages/index/index.wxml @@ -0,0 +1,106 @@ + + + + + 欢迎使用保险服务 + 专业、安全、便捷的保险服务平台 + + + + + + 📋 + 保险产品 + + + 📄 + 我的保单 + + + 💰 + 理赔申请 + + + 📞 + 客服服务 + + + + + + + 热门产品 + 更多 > + + + + + {{item.icon}} + + {{item.name}} + {{item.description}} + + 起保费: + ¥{{item.min_premium}} + + + + + + + + + + 服务优势 + + + + + 🛡️ + 专业保障 + 专业团队提供全方位保险咨询 + + + + 快速理赔 + 7x24小时快速理赔服务 + + + 🔒 + 安全可靠 + 银行级安全保障体系 + + + + + + + + 最新资讯 + 更多 > + + + + + + {{item.title}} + {{item.summary}} + {{item.date}} + + > + + + + \ No newline at end of file diff --git a/insurance_mini_program/pages/index/index.wxss b/insurance_mini_program/pages/index/index.wxss new file mode 100644 index 0000000..cd03fd6 --- /dev/null +++ b/insurance_mini_program/pages/index/index.wxss @@ -0,0 +1,233 @@ +/* pages/index/index.wxss */ +.container { + background-color: #f5f5f5; + min-height: 100vh; +} + +/* 欢迎横幅 */ +.welcome-banner { + background: linear-gradient(135deg, #1890ff, #40a9ff); + padding: 60rpx 30rpx; + text-align: center; + color: white; +} + +.welcome-title { + font-size: 48rpx; + font-weight: bold; + display: block; + margin-bottom: 20rpx; +} + +.welcome-subtitle { + font-size: 28rpx; + opacity: 0.9; + display: block; +} + +/* 快捷入口 */ +.quick-actions { + display: flex; + justify-content: space-around; + padding: 40rpx 20rpx; + background: #fff; + margin-bottom: 20rpx; +} + +.action-item { + display: flex; + flex-direction: column; + align-items: center; +} + +.action-icon { + font-size: 60rpx; + margin-bottom: 20rpx; + width: 80rpx; + height: 80rpx; + display: flex; + align-items: center; + justify-content: center; + background: #f0f8ff; + border-radius: 50%; +} + +.action-text { + font-size: 24rpx; + color: #666; +} + +/* 通用区块 */ +.section { + margin-bottom: 20rpx; + background: #fff; + padding: 30rpx; +} + +.section-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30rpx; +} + +.section-title { + font-size: 36rpx; + font-weight: bold; + color: #333; +} + +.section-more { + color: #1890ff; + font-size: 28rpx; +} + +/* 产品网格 */ +.product-grid { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.product-card { + display: flex; + padding: 30rpx; + border: 1px solid #eee; + border-radius: 12rpx; + background: #fafafa; +} + +.product-icon { + font-size: 60rpx; + width: 120rpx; + height: 120rpx; + margin-right: 30rpx; + border-radius: 8rpx; + display: flex; + align-items: center; + justify-content: center; + background: #f0f8ff; +} + +.product-info { + flex: 1; +} + +.product-name { + font-size: 32rpx; + font-weight: bold; + margin-bottom: 10rpx; + color: #333; +} + +.product-desc { + font-size: 28rpx; + color: #666; + margin-bottom: 15rpx; +} + +.product-price { + display: flex; + align-items: center; +} + +.price-label { + font-size: 24rpx; + color: #999; +} + +.price-value { + font-size: 32rpx; + color: #ff6b35; + font-weight: bold; +} + +/* 优势网格 */ +.advantage-grid { + display: flex; + justify-content: space-between; +} + +.advantage-item { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 0 20rpx; +} + +.advantage-icon { + font-size: 60rpx; + width: 100rpx; + height: 100rpx; + margin-bottom: 20rpx; + display: flex; + align-items: center; + justify-content: center; + background: #f0f8ff; + border-radius: 50%; +} + +.advantage-title { + font-size: 28rpx; + font-weight: bold; + margin-bottom: 10rpx; + color: #333; +} + +.advantage-desc { + font-size: 24rpx; + color: #666; + line-height: 1.4; +} + +/* 新闻列表 */ +.news-list { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.news-item { + display: flex; + align-items: center; + padding: 20rpx 0; + border-bottom: 1px solid #f0f0f0; +} + +.news-item:last-child { + border-bottom: none; +} + +.news-content { + flex: 1; +} + +.news-title { + font-size: 30rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; + display: block; +} + +.news-summary { + font-size: 26rpx; + color: #666; + margin-bottom: 10rpx; + display: block; + line-height: 1.4; +} + +.news-date { + font-size: 22rpx; + color: #999; + display: block; +} + +.news-arrow { + font-size: 24rpx; + color: #ccc; + margin-left: 20rpx; +} \ No newline at end of file diff --git a/insurance_mini_program/pages/login/login.js b/insurance_mini_program/pages/login/login.js new file mode 100644 index 0000000..7e71244 --- /dev/null +++ b/insurance_mini_program/pages/login/login.js @@ -0,0 +1,404 @@ +// pages/login/login.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 登录方式:password 或 sms + loginType: 'password', + + // 表单数据 + formData: { + phone: '', + password: '', + smsCode: '' + }, + + // 密码显示状态 + showPassword: false, + + // 记住密码 + rememberMe: false, + + // 同意协议 + agreeTerms: false, + + // 加载状态 + loading: false, + + // 短信倒计时 + smsCountdown: 0, + + // 手机号是否有效 + isValidPhone: false + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('登录页面加载完成') + this.loadSavedData() + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('登录页面渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('登录页面显示') + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('登录页面隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('登录页面卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保险服务 - 专业安全的保险平台', + path: '/pages/login/login', + imageUrl: '/static/images/share-login.jpg' + } + }, + + /** + * 加载保存的数据 + */ + loadSavedData() { + const savedPhone = wx.getStorageSync('savedPhone') + const savedPassword = wx.getStorageSync('savedPassword') + const rememberMe = wx.getStorageSync('rememberMe') + + if (savedPhone && rememberMe) { + this.setData({ + 'formData.phone': savedPhone, + 'formData.password': savedPassword || '', + rememberMe: rememberMe + }) + this.validateForm() + } + }, + + /** + * 切换登录方式 + */ + switchLoginType(e) { + const type = e.currentTarget.dataset.type + console.log('切换登录方式:', type) + this.setData({ + loginType: type, + 'formData.smsCode': '' + }) + }, + + /** + * 手机号输入 + */ + onPhoneInput(e) { + const phone = e.detail.value + this.setData({ + 'formData.phone': phone + }) + this.validateForm() + }, + + /** + * 密码输入 + */ + onPasswordInput(e) { + const password = e.detail.value + this.setData({ + 'formData.password': password + }) + this.validateForm() + }, + + /** + * 验证码输入 + */ + onSmsCodeInput(e) { + const smsCode = e.detail.value + this.setData({ + 'formData.smsCode': smsCode + }) + this.validateForm() + }, + + /** + * 切换密码显示 + */ + togglePassword() { + this.setData({ + showPassword: !this.data.showPassword + }) + }, + + /** + * 记住密码切换 + */ + onRememberChange(e) { + this.setData({ + rememberMe: e.detail.value + }) + }, + + /** + * 同意协议切换 + */ + onAgreeChange(e) { + this.setData({ + agreeTerms: e.detail.value + }) + }, + + /** + * 验证表单 + */ + validateForm() { + const { phone, password, smsCode } = this.data.formData + const { loginType } = this.data + + // 验证手机号 + const isValidPhone = /^1[3-9]\d{9}$/.test(phone) + this.setData({ isValidPhone }) + + // 验证密码登录 + if (loginType === 'password') { + const canLogin = isValidPhone && password.length >= 6 + this.setData({ canLogin }) + } + + // 验证短信登录 + if (loginType === 'sms') { + const canSmsLogin = isValidPhone && smsCode.length === 6 + this.setData({ canSmsLogin }) + } + }, + + /** + * 发送短信验证码 + */ + sendSmsCode() { + const { phone } = this.data.formData + const { isValidPhone, smsCountdown } = this.data + + if (!isValidPhone) { + wx.showToast({ + title: '请输入正确的手机号', + icon: 'none' + }) + return + } + + if (smsCountdown > 0) { + return + } + + console.log('发送短信验证码:', phone) + + // 模拟发送验证码 + wx.showLoading({ + title: '发送中...' + }) + + setTimeout(() => { + wx.hideLoading() + wx.showToast({ + title: '验证码已发送', + icon: 'success' + }) + + // 开始倒计时 + this.startCountdown() + }, 1000) + }, + + /** + * 开始倒计时 + */ + startCountdown() { + let countdown = 60 + this.setData({ smsCountdown: countdown }) + + const timer = setInterval(() => { + countdown-- + this.setData({ smsCountdown: countdown }) + + if (countdown <= 0) { + clearInterval(timer) + } + }, 1000) + }, + + /** + * 密码登录 + */ + onPasswordLogin() { + const { phone, password } = this.data.formData + const { canLogin, loading, agreeTerms } = this.data + + if (!canLogin || loading) return + + if (!agreeTerms) { + wx.showToast({ + title: '请先同意用户协议', + icon: 'none' + }) + return + } + + console.log('密码登录:', phone) + this.performLogin('password', { phone, password }) + }, + + /** + * 短信登录 + */ + onSmsLogin() { + const { phone, smsCode } = this.data.formData + const { canSmsLogin, loading, agreeTerms } = this.data + + if (!canSmsLogin || loading) return + + if (!agreeTerms) { + wx.showToast({ + title: '请先同意用户协议', + icon: 'none' + }) + return + } + + console.log('短信登录:', phone, smsCode) + this.performLogin('sms', { phone, smsCode }) + }, + + /** + * 执行登录 + */ + performLogin(type, data) { + this.setData({ loading: true }) + + // 模拟登录API调用 + setTimeout(() => { + this.setData({ loading: false }) + + // 模拟登录成功 + const mockUserInfo = { + id: 1, + nickname: '用户' + data.phone.slice(-4), + phone: data.phone, + avatar: '' + } + + // 保存登录信息 + wx.setStorageSync('token', 'mock_token_' + Date.now()) + wx.setStorageSync('userInfo', mockUserInfo) + + // 保存密码(如果选择记住密码) + if (this.data.rememberMe && type === 'password') { + wx.setStorageSync('savedPhone', data.phone) + wx.setStorageSync('savedPassword', data.password) + wx.setStorageSync('rememberMe', true) + } + + wx.showToast({ + title: '登录成功', + icon: 'success' + }) + + // 延迟跳转 + setTimeout(() => { + wx.switchTab({ + url: '/pages/my/my' + }) + }, 1500) + + }, 2000) + }, + + /** + * 微信登录 + */ + onWechatLogin() { + console.log('微信登录') + wx.showToast({ + title: '微信登录功能开发中', + icon: 'none' + }) + }, + + /** + * 跳转到注册页 + */ + goToRegister() { + console.log('跳转到注册页') + wx.navigateTo({ + url: '/pages/register/register' + }) + }, + + /** + * 跳转到忘记密码页 + */ + goToForgotPassword() { + console.log('跳转到忘记密码页') + wx.navigateTo({ + url: '/pages/forgot-password/forgot-password' + }) + }, + + /** + * 跳转到用户协议页 + */ + goToTerms() { + console.log('跳转到用户协议页') + wx.navigateTo({ + url: '/pages/terms/terms' + }) + }, + + /** + * 跳转到隐私政策页 + */ + goToPrivacy() { + console.log('跳转到隐私政策页') + wx.navigateTo({ + url: '/pages/privacy/privacy' + }) + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/login/login.json b/insurance_mini_program/pages/login/login.json new file mode 100644 index 0000000..89d0d88 --- /dev/null +++ b/insurance_mini_program/pages/login/login.json @@ -0,0 +1,7 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "登录", + "navigationStyle": "custom", + "backgroundColor": "#667eea", + "backgroundTextStyle": "light" +} \ No newline at end of file diff --git a/insurance_mini_program/pages/login/login.wxml b/insurance_mini_program/pages/login/login.wxml new file mode 100644 index 0000000..0182dfe --- /dev/null +++ b/insurance_mini_program/pages/login/login.wxml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + 🛡️ + 保险服务 + 专业、安全、便捷的保险平台 + + + + + + + + + + 📱 + + + + 🔒 + + + {{showPassword ? '👁️' : '👁️‍🗨️'}} + + + + + + + + 记住密码 + + 忘记密码? + + + + + + + + + + 📱 + + + + 📨 + + + + + + + + + + + + + + 还没有账号? + 立即注册 + + + + + + + 我已阅读并同意 + 《用户协议》 + 和 + 《隐私政策》 + + + + \ No newline at end of file diff --git a/insurance_mini_program/pages/login/login.wxss b/insurance_mini_program/pages/login/login.wxss new file mode 100644 index 0000000..1e19043 --- /dev/null +++ b/insurance_mini_program/pages/login/login.wxss @@ -0,0 +1,356 @@ +/* pages/login/login.wxss */ +.container { + min-height: 100vh; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + position: relative; + overflow: hidden; +} + +/* 顶部装饰 */ +.header-decoration { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 200rpx; + overflow: hidden; +} + +.decoration-circle { + position: absolute; + border-radius: 50%; + background: rgba(255, 255, 255, 0.1); +} + +.circle-1 { + width: 200rpx; + height: 200rpx; + top: -100rpx; + right: -50rpx; +} + +.circle-2 { + width: 150rpx; + height: 150rpx; + top: 50rpx; + left: -75rpx; +} + +.circle-3 { + width: 100rpx; + height: 100rpx; + top: 20rpx; + right: 100rpx; +} + +/* 登录表单 */ +.login-form { + position: relative; + z-index: 10; + padding: 100rpx 60rpx 60rpx; +} + +/* Logo区域 */ +.logo-section { + text-align: center; + margin-bottom: 80rpx; +} + +.logo-icon { + font-size: 120rpx; + margin-bottom: 30rpx; +} + +.app-name { + font-size: 48rpx; + font-weight: bold; + color: white; + margin-bottom: 20rpx; + display: block; +} + +.app-slogan { + font-size: 28rpx; + color: rgba(255, 255, 255, 0.8); + display: block; +} + +/* 登录方式切换 */ +.login-tabs { + display: flex; + background: rgba(255, 255, 255, 0.1); + border-radius: 50rpx; + padding: 8rpx; + margin-bottom: 60rpx; +} + +.tab-item { + flex: 1; + text-align: center; + padding: 20rpx; + border-radius: 42rpx; + font-size: 28rpx; + color: rgba(255, 255, 255, 0.7); + transition: all 0.3s; +} + +.tab-item.active { + background: white; + color: #1890ff; + font-weight: bold; +} + +/* 表单内容 */ +.form-content { + background: white; + border-radius: 20rpx; + padding: 60rpx 40rpx; + box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.1); +} + +.input-group { + margin-bottom: 40rpx; +} + +.input-wrapper { + position: relative; + margin-bottom: 30rpx; + display: flex; + align-items: center; + background: #f8f9fa; + border-radius: 12rpx; + padding: 0 20rpx; + border: 2rpx solid transparent; + transition: all 0.3s; +} + +.input-wrapper:focus-within { + border-color: #1890ff; + background: white; +} + +.input-icon { + font-size: 32rpx; + margin-right: 20rpx; + color: #999; +} + +.form-input { + flex: 1; + height: 80rpx; + font-size: 30rpx; + color: #333; + background: transparent; +} + +.password-toggle { + padding: 10rpx; + font-size: 32rpx; + color: #999; +} + +.sms-input { + padding-right: 0; +} + +.sms-btn { + background: #1890ff; + color: white; + border: none; + border-radius: 8rpx; + font-size: 24rpx; + padding: 20rpx 30rpx; + margin-left: 20rpx; + white-space: nowrap; +} + +.sms-btn.disabled { + background: #ccc; + color: #999; +} + +.sms-btn::after { + border: none; +} + +/* 表单选项 */ +.form-options { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 40rpx; +} + +.remember-me { + display: flex; + align-items: center; +} + +.remember-text { + font-size: 26rpx; + color: #666; + margin-left: 10rpx; +} + +.forgot-password { + font-size: 26rpx; + color: #1890ff; +} + +/* 登录按钮 */ +.login-btn { + width: 100%; + height: 88rpx; + border-radius: 44rpx; + font-size: 32rpx; + font-weight: bold; + border: none; + margin-bottom: 40rpx; + transition: all 0.3s; +} + +.login-btn.active { + background: #1890ff; + color: white; +} + +.login-btn.disabled { + background: #f0f0f0; + color: #ccc; +} + +.login-btn::after { + border: none; +} + +/* 其他登录方式 */ +.other-login { + margin-bottom: 40rpx; +} + +.divider { + text-align: center; + margin-bottom: 30rpx; + position: relative; +} + +.divider::before { + content: ''; + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 1rpx; + background: #e8e8e8; +} + +.divider-text { + background: white; + padding: 0 30rpx; + font-size: 24rpx; + color: #999; + position: relative; + z-index: 1; +} + +.social-login { + display: flex; + justify-content: center; +} + +.social-btn { + display: flex; + align-items: center; + padding: 20rpx 40rpx; + border-radius: 25rpx; + font-size: 26rpx; + border: 2rpx solid #e8e8e8; + background: white; + color: #333; +} + +.social-btn::after { + border: none; +} + +.wechat-btn { + border-color: #07c160; + color: #07c160; +} + +.social-icon { + font-size: 32rpx; + margin-right: 10rpx; +} + +.social-text { + font-size: 26rpx; +} + +/* 注册提示 */ +.register-tip { + text-align: center; + margin-bottom: 30rpx; +} + +.tip-text { + font-size: 26rpx; + color: #666; +} + +.register-link { + font-size: 26rpx; + color: #1890ff; + margin-left: 10rpx; +} + +/* 用户协议 */ +.agreement { + display: flex; + align-items: flex-start; + font-size: 22rpx; + color: #999; + line-height: 1.5; +} + +.agreement-text { + margin-left: 10rpx; + flex: 1; +} + +.link { + color: #1890ff; +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .login-form { + padding: 80rpx 40rpx 40rpx; + } + + .form-content { + padding: 40rpx 30rpx; + } +} + +/* 动画效果 */ +.tab-item { + transition: all 0.3s ease; +} + +.input-wrapper { + transition: all 0.3s ease; +} + +.login-btn { + transition: all 0.3s ease; +} + +.social-btn:active { + transform: scale(0.95); +} + +/* 加载状态 */ +.login-btn:disabled { + opacity: 0.6; +} \ No newline at end of file diff --git a/insurance_mini_program/pages/my/my.js b/insurance_mini_program/pages/my/my.js new file mode 100644 index 0000000..a2a95e5 --- /dev/null +++ b/insurance_mini_program/pages/my/my.js @@ -0,0 +1,336 @@ +// pages/my/my.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 登录状态 + isLoggedIn: false, + + // 用户信息 + userInfo: { + nickname: '', + phone: '', + avatar: '' + }, + + // 统计数据 + stats: { + policyCount: 0, + applicationCount: 0, + claimCount: 0, + favoriteCount: 0 + } + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('我的页面加载完成') + this.checkLoginStatus() + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('我的页面渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('我的页面显示') + this.checkLoginStatus() + if (this.data.isLoggedIn) { + this.loadUserData() + } + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('我的页面隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('我的页面卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.checkLoginStatus() + if (this.data.isLoggedIn) { + this.loadUserData() + } + // 停止下拉刷新 + setTimeout(() => { + wx.stopPullDownRefresh() + }, 1000) + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保险服务 - 专业安全的保险平台', + path: '/pages/my/my', + imageUrl: '/static/images/share-my.jpg' + } + }, + + /** + * 检查登录状态 + */ + checkLoginStatus() { + const token = wx.getStorageSync('token') + const userInfo = wx.getStorageSync('userInfo') + + if (token && userInfo) { + this.setData({ + isLoggedIn: true, + userInfo: userInfo + }) + } else { + this.setData({ + isLoggedIn: false, + userInfo: { + nickname: '', + phone: '', + avatar: '' + } + }) + } + }, + + /** + * 加载用户数据 + */ + loadUserData() { + console.log('加载用户数据') + // 模拟加载用户统计数据 + this.setData({ + stats: { + policyCount: 3, + applicationCount: 2, + claimCount: 1, + favoriteCount: 5 + } + }) + }, + + /** + * 跳转到登录页 + */ + goToLogin() { + console.log('跳转到登录页') + wx.navigateTo({ + url: '/pages/login/login' + }) + }, + + /** + * 跳转到个人资料页 + */ + goToProfile() { + console.log('跳转到个人资料页') + if (!this.data.isLoggedIn) { + this.goToLogin() + return + } + wx.navigateTo({ + url: '/pages/profile/profile' + }) + }, + + /** + * 跳转到我的保单页 + */ + goToPolicies() { + console.log('跳转到我的保单页') + if (!this.data.isLoggedIn) { + this.goToLogin() + return + } + wx.navigateTo({ + url: '/pages/policies/policies' + }) + }, + + /** + * 跳转到投保申请页 + */ + goToApplications() { + console.log('跳转到投保申请页') + if (!this.data.isLoggedIn) { + this.goToLogin() + return + } + wx.navigateTo({ + url: '/pages/application/application' + }) + }, + + /** + * 跳转到理赔申请页 + */ + goToClaims() { + console.log('跳转到理赔申请页') + if (!this.data.isLoggedIn) { + this.goToLogin() + return + } + wx.navigateTo({ + url: '/pages/claims/claims' + }) + }, + + /** + * 跳转到收藏产品页 + */ + goToFavorites() { + console.log('跳转到收藏产品页') + if (!this.data.isLoggedIn) { + this.goToLogin() + return + } + wx.navigateTo({ + url: '/pages/favorites/favorites' + }) + }, + + /** + * 跳转到设置页 + */ + goToSettings() { + console.log('跳转到设置页') + wx.navigateTo({ + url: '/pages/settings/settings' + }) + }, + + /** + * 跳转到安全中心页 + */ + goToSecurity() { + console.log('跳转到安全中心页') + if (!this.data.isLoggedIn) { + this.goToLogin() + return + } + wx.navigateTo({ + url: '/pages/security/security' + }) + }, + + /** + * 跳转到帮助中心页 + */ + goToHelp() { + console.log('跳转到帮助中心页') + wx.navigateTo({ + url: '/pages/help/help' + }) + }, + + /** + * 联系客服 + */ + goToContact() { + console.log('联系客服') + wx.showModal({ + title: '联系客服', + content: '客服电话:400-888-8888\n服务时间:周一至周日 9:00-18:00\n\n您也可以在线咨询客服', + showCancel: true, + cancelText: '取消', + confirmText: '拨打电话', + success: (res) => { + if (res.confirm) { + wx.makePhoneCall({ + phoneNumber: '400-888-8888' + }) + } + } + }) + }, + + /** + * 跳转到意见反馈页 + */ + goToFeedback() { + console.log('跳转到意见反馈页') + wx.navigateTo({ + url: '/pages/feedback/feedback' + }) + }, + + /** + * 跳转到关于我们页 + */ + goToAbout() { + console.log('跳转到关于我们页') + wx.navigateTo({ + url: '/pages/about/about' + }) + }, + + /** + * 退出登录 + */ + onLogout() { + console.log('退出登录') + wx.showModal({ + title: '确认退出', + content: '确定要退出登录吗?', + showCancel: true, + cancelText: '取消', + confirmText: '确定', + success: (res) => { + if (res.confirm) { + // 清除本地存储 + wx.removeStorageSync('token') + wx.removeStorageSync('userInfo') + + // 更新页面状态 + this.setData({ + isLoggedIn: false, + userInfo: { + nickname: '', + phone: '', + avatar: '' + }, + stats: { + policyCount: 0, + applicationCount: 0, + claimCount: 0, + favoriteCount: 0 + } + }) + + wx.showToast({ + title: '已退出登录', + icon: 'success' + }) + } + } + }) + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/my/my.json b/insurance_mini_program/pages/my/my.json new file mode 100644 index 0000000..bdb56f0 --- /dev/null +++ b/insurance_mini_program/pages/my/my.json @@ -0,0 +1,7 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "我的", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5" +} \ No newline at end of file diff --git a/insurance_mini_program/pages/my/my.wxml b/insurance_mini_program/pages/my/my.wxml new file mode 100644 index 0000000..28ebb17 --- /dev/null +++ b/insurance_mini_program/pages/my/my.wxml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + {{stats.policyCount}} + 我的保单 + + + {{stats.applicationCount}} + 投保申请 + + + {{stats.claimCount}} + 理赔申请 + + + {{stats.favoriteCount}} + 收藏产品 + + + + + + + + + 我的服务 + + + 📄 + 我的保单 + {{stats.policyCount}} + > + + + 📝 + 投保申请 + {{stats.applicationCount}} + > + + + 💰 + 理赔申请 + {{stats.claimCount}} + > + + + ❤️ + 收藏产品 + {{stats.favoriteCount}} + > + + + + + + + 账户管理 + + + 👤 + 个人资料 + > + + + ⚙️ + 设置 + > + + + 🔒 + 安全中心 + > + + + + + + + 帮助支持 + + + + 帮助中心 + > + + + 📞 + 联系客服 + > + + + 💬 + 意见反馈 + > + + + ℹ️ + 关于我们 + > + + + + + + + + + + \ No newline at end of file diff --git a/insurance_mini_program/pages/my/my.wxss b/insurance_mini_program/pages/my/my.wxss new file mode 100644 index 0000000..9c75325 --- /dev/null +++ b/insurance_mini_program/pages/my/my.wxss @@ -0,0 +1,219 @@ +/* pages/my/my.wxss */ +.container { + background-color: #f5f5f5; + min-height: 100vh; +} + +/* 用户信息区域 */ +.user-section { + background: linear-gradient(135deg, #1890ff, #40a9ff); + padding: 40rpx 30rpx 60rpx; + color: white; +} + +.user-info { + display: flex; + align-items: center; + margin-bottom: 30rpx; +} + +.avatar { + width: 120rpx; + height: 120rpx; + border-radius: 60rpx; + background: rgba(255, 255, 255, 0.2); + display: flex; + align-items: center; + justify-content: center; + margin-right: 30rpx; + overflow: hidden; +} + +.avatar-img { + width: 100%; + height: 100%; + border-radius: 60rpx; +} + +.avatar-text { + font-size: 48rpx; + font-weight: bold; + color: white; +} + +.user-details { + flex: 1; +} + +.username { + font-size: 36rpx; + font-weight: bold; + margin-bottom: 10rpx; + display: block; +} + +.user-phone { + font-size: 28rpx; + opacity: 0.8; + display: block; +} + +.arrow-icon { + font-size: 32rpx; + opacity: 0.8; +} + +.login-prompt { + text-align: center; +} + +.login-btn { + background: rgba(255, 255, 255, 0.2); + color: white; + border: 2rpx solid rgba(255, 255, 255, 0.3); + border-radius: 30rpx; + font-size: 28rpx; + padding: 20rpx 60rpx; +} + +/* 数据统计 */ +.stats-section { + background: white; + margin: -30rpx 30rpx 20rpx; + border-radius: 12rpx; + padding: 30rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1); +} + +.stats-grid { + display: flex; + justify-content: space-around; +} + +.stat-item { + text-align: center; + flex: 1; +} + +.stat-number { + font-size: 48rpx; + font-weight: bold; + color: #1890ff; + display: block; + margin-bottom: 10rpx; +} + +.stat-label { + font-size: 24rpx; + color: #666; + display: block; +} + +/* 功能菜单 */ +.menu-section { + padding: 0 30rpx; +} + +.menu-group { + margin-bottom: 30rpx; +} + +.group-title { + font-size: 28rpx; + color: #999; + margin-bottom: 20rpx; + padding-left: 10rpx; +} + +.menu-list { + background: white; + border-radius: 12rpx; + overflow: hidden; + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.menu-item { + display: flex; + align-items: center; + padding: 30rpx; + border-bottom: 1rpx solid #f0f0f0; + position: relative; +} + +.menu-item:last-child { + border-bottom: none; +} + +.menu-icon { + font-size: 40rpx; + margin-right: 30rpx; + width: 50rpx; + text-align: center; +} + +.menu-text { + flex: 1; + font-size: 30rpx; + color: #333; +} + +.menu-badge { + background: #ff4d4f; + color: white; + font-size: 20rpx; + padding: 4rpx 12rpx; + border-radius: 20rpx; + margin-right: 20rpx; + min-width: 30rpx; + text-align: center; +} + +.menu-arrow { + font-size: 24rpx; + color: #ccc; +} + +/* 退出登录 */ +.logout-section { + padding: 30rpx; +} + +.logout-btn { + background: #ff4d4f; + color: white; + border: none; + border-radius: 12rpx; + font-size: 30rpx; + padding: 25rpx; + width: 100%; +} + +.logout-btn::after { + border: none; +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .stats-grid { + flex-wrap: wrap; + } + + .stat-item { + width: 50%; + margin-bottom: 20rpx; + } +} + +/* 动画效果 */ +.menu-item { + transition: background-color 0.3s; +} + +.menu-item:active { + background-color: #f8f8f8; +} + +.stat-item:active { + transform: scale(0.95); + transition: transform 0.2s; +} \ No newline at end of file diff --git a/insurance_mini_program/pages/policies/policies.js b/insurance_mini_program/pages/policies/policies.js new file mode 100644 index 0000000..d27d8ad --- /dev/null +++ b/insurance_mini_program/pages/policies/policies.js @@ -0,0 +1,316 @@ +// pages/policies/policies.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 当前激活的标签 + activeTab: 'all', + + // 保单列表 + policiesList: [], + + // 过滤后的保单列表 + filteredPolicies: [], + + // 统计数据 + stats: { + totalPolicies: 0, + activePolicies: 0, + expiringPolicies: 0 + }, + + // 加载状态 + loading: false, + + // 是否有更多数据 + hasMore: true, + + // 当前页码 + currentPage: 1 + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('我的保单页加载', options) + this.loadPoliciesList() + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('我的保单页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('我的保单页显示') + this.loadPoliciesList() + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('我的保单页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('我的保单页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.setData({ + currentPage: 1, + hasMore: true + }) + this.loadPoliciesList() + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + if (this.data.hasMore && !this.data.loading) { + this.loadMore() + } + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '我的保单', + path: '/pages/policies/policies', + imageUrl: '/static/images/share-policies.jpg' + } + }, + + /** + * 加载保单列表 + */ + loadPoliciesList() { + this.setData({ loading: true }) + + console.log('加载保单列表') + + // 模拟API调用 + setTimeout(() => { + const mockPolicies = this.getMockPolicies() + this.setData({ + policiesList: mockPolicies, + filteredPolicies: this.filterPolicies(mockPolicies, this.data.activeTab), + stats: this.calculateStats(mockPolicies), + loading: false + }) + }, 1000) + }, + + /** + * 获取模拟保单数据 + */ + getMockPolicies() { + return [ + { + id: '1', + name: '综合意外伤害保险', + description: '全面保障,安心出行', + status: 'active', + statusText: '有效', + policyNo: 'POL20240115001', + coverageAmount: 50, + premium: 299, + effectiveDate: '2024-01-15', + expiryDate: '2025-01-15' + }, + { + id: '2', + name: '重大疾病保险', + description: '重疾保障,守护健康', + status: 'active', + statusText: '有效', + policyNo: 'POL20240110002', + coverageAmount: 30, + premium: 1200, + effectiveDate: '2024-01-10', + expiryDate: '2025-01-10' + }, + { + id: '3', + name: '定期寿险', + description: '家庭保障,责任担当', + status: 'expiring', + statusText: '即将到期', + policyNo: 'POL20231201003', + coverageAmount: 100, + premium: 800, + effectiveDate: '2023-12-01', + expiryDate: '2024-12-01' + }, + { + id: '4', + name: '医疗保险', + description: '医疗费用,安心报销', + status: 'expired', + statusText: '已过期', + policyNo: 'POL20221101004', + coverageAmount: 20, + premium: 500, + effectiveDate: '2022-11-01', + expiryDate: '2023-11-01' + }, + { + id: '5', + name: '车险', + description: '车辆保障,出行无忧', + status: 'active', + statusText: '有效', + policyNo: 'POL20240120005', + coverageAmount: 200, + premium: 3000, + effectiveDate: '2024-01-20', + expiryDate: '2025-01-20' + } + ] + }, + + /** + * 过滤保单列表 + */ + filterPolicies(policies, status) { + if (status === 'all') { + return policies + } + return policies.filter(policy => policy.status === status) + }, + + /** + * 计算统计数据 + */ + calculateStats(policies) { + const totalPolicies = policies.length + const activePolicies = policies.filter(policy => policy.status === 'active').length + const expiringPolicies = policies.filter(policy => policy.status === 'expiring').length + + return { + totalPolicies, + activePolicies, + expiringPolicies + } + }, + + /** + * 切换标签 + */ + switchTab(e) { + const tab = e.currentTarget.dataset.tab + console.log('切换标签:', tab) + + this.setData({ + activeTab: tab, + filteredPolicies: this.filterPolicies(this.data.policiesList, tab) + }) + }, + + /** + * 跳转到保单详情 + */ + goToPolicyDetail(e) { + const policyId = e.currentTarget.dataset.id + console.log('跳转到保单详情:', policyId) + wx.navigateTo({ + url: `/pages/policy-detail/policy-detail?id=${policyId}` + }) + }, + + /** + * 跳转到新保单投保 + */ + goToNewPolicy() { + console.log('跳转到新保单投保') + wx.switchTab({ + url: '/pages/products/products' + }) + }, + + /** + * 跳转到续保 + */ + goToRenewal(e) { + const policyId = e.currentTarget.dataset.id + console.log('跳转到续保:', policyId) + wx.navigateTo({ + url: `/pages/renewal/renewal?policyId=${policyId}` + }) + }, + + /** + * 跳转到理赔申请 + */ + goToClaim(e) { + const policyId = e.currentTarget.dataset.id + console.log('跳转到理赔申请:', policyId) + wx.navigateTo({ + url: `/pages/claims/claims?policyId=${policyId}` + }) + }, + + /** + * 加载更多 + */ + loadMore() { + if (this.data.loading || !this.data.hasMore) return + + this.setData({ loading: true }) + + console.log('加载更多保单数据') + + // 模拟加载更多数据 + setTimeout(() => { + const newPolicies = this.getMockPolicies().map((policy, index) => ({ + ...policy, + id: (this.data.policiesList.length + index + 1).toString(), + policyNo: 'POL' + (Date.now() + index), + effectiveDate: this.formatDate(new Date(Date.now() - Math.random() * 365 * 24 * 60 * 60 * 1000)), + expiryDate: this.formatDate(new Date(Date.now() + Math.random() * 365 * 24 * 60 * 60 * 1000)) + })) + + const updatedPolicies = [...this.data.policiesList, ...newPolicies] + + this.setData({ + policiesList: updatedPolicies, + filteredPolicies: this.filterPolicies(updatedPolicies, this.data.activeTab), + stats: this.calculateStats(updatedPolicies), + loading: false, + hasMore: updatedPolicies.length < 20 // 模拟最多20条数据 + }) + }, 1000) + }, + + /** + * 格式化日期 + */ + formatDate(date) { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + + return `${year}-${month}-${day}` + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/policies/policies.json b/insurance_mini_program/pages/policies/policies.json new file mode 100644 index 0000000..5d4ba7f --- /dev/null +++ b/insurance_mini_program/pages/policies/policies.json @@ -0,0 +1,8 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "我的保单", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5", + "onReachBottomDistance": 50 +} \ No newline at end of file diff --git a/insurance_mini_program/pages/policies/policies.wxml b/insurance_mini_program/pages/policies/policies.wxml new file mode 100644 index 0000000..3751cf0 --- /dev/null +++ b/insurance_mini_program/pages/policies/policies.wxml @@ -0,0 +1,155 @@ + + + + + + 我的保单 + 管理您的保险保单 + + + + + + + + + + + {{stats.totalPolicies}} + 总保单数 + + + {{stats.activePolicies}} + 有效保单 + + + {{stats.expiringPolicies}} + 即将到期 + + + + + + + + 全部 + + + 有效 + + + 已过期 + + + 即将到期 + + + + + + + + + {{item.name}} + {{item.description}} + + + {{item.statusText}} + + + + + + 保单号: + {{item.policyNo}} + + + 保险金额: + ¥{{item.coverageAmount}}万 + + + 保费: + ¥{{item.premium}}/年 + + + 生效日期: + {{item.effectiveDate}} + + + 到期日期: + {{item.expiryDate}} + + + + + + + + + + + + + + 📄 + 暂无保单 + 您还没有任何保险保单 + + + + + + 加载中... + 加载更多 + + \ No newline at end of file diff --git a/insurance_mini_program/pages/policies/policies.wxss b/insurance_mini_program/pages/policies/policies.wxss new file mode 100644 index 0000000..386a58f --- /dev/null +++ b/insurance_mini_program/pages/policies/policies.wxss @@ -0,0 +1,374 @@ +/* pages/policies/policies.wxss */ +.container { + background: #f5f5f5; + min-height: 100vh; +} + +/* 页面头部 */ +.header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + padding: 30rpx; + display: flex; + justify-content: space-between; + align-items: center; + color: white; +} + +.header-content { + flex: 1; +} + +.header-title { + font-size: 36rpx; + font-weight: bold; + margin-bottom: 10rpx; + display: block; +} + +.header-desc { + font-size: 24rpx; + opacity: 0.9; + display: block; +} + +.header-actions { + margin-left: 20rpx; +} + +.action-btn { + display: flex; + align-items: center; + padding: 15rpx 25rpx; + background: rgba(255, 255, 255, 0.2); + border: 2rpx solid rgba(255, 255, 255, 0.3); + border-radius: 25rpx; + color: white; + font-size: 24rpx; + transition: all 0.3s; +} + +.action-btn::after { + border: none; +} + +.action-btn:active { + background: rgba(255, 255, 255, 0.3); + transform: scale(0.95); +} + +.btn-icon { + font-size: 28rpx; + margin-right: 8rpx; +} + +.btn-text { + font-size: 24rpx; +} + +/* 保单统计 */ +.stats-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.stats-card { + display: flex; + justify-content: space-around; +} + +.stat-item { + text-align: center; +} + +.stat-number { + font-size: 48rpx; + font-weight: bold; + color: #1890ff; + margin-bottom: 10rpx; + display: block; +} + +.stat-label { + font-size: 24rpx; + color: #666; +} + +/* 筛选标签 */ +.filter-tabs { + background: white; + display: flex; + padding: 0 30rpx; + border-bottom: 1rpx solid #e8e8e8; +} + +.tab-item { + flex: 1; + text-align: center; + padding: 30rpx 0; + font-size: 28rpx; + color: #666; + position: relative; + transition: all 0.3s; +} + +.tab-item.active { + color: #1890ff; + font-weight: bold; +} + +.tab-item.active::after { + content: ''; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 60rpx; + height: 4rpx; + background: #1890ff; + border-radius: 2rpx; +} + +/* 保单列表 */ +.policies-list { + padding: 20rpx; +} + +.policy-item { + background: white; + border-radius: 16rpx; + padding: 30rpx; + margin-bottom: 20rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); + transition: all 0.3s; +} + +.policy-item:active { + transform: scale(0.98); + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15); +} + +.policy-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 20rpx; +} + +.policy-info { + flex: 1; +} + +.policy-name { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 8rpx; + display: block; +} + +.policy-desc { + font-size: 24rpx; + color: #666; + line-height: 1.4; +} + +.policy-status { + padding: 8rpx 16rpx; + border-radius: 20rpx; + font-size: 22rpx; + font-weight: bold; +} + +.policy-status.active { + background: #f6ffed; + color: #52c41a; +} + +.policy-status.expiring { + background: #fff7e6; + color: #d48806; +} + +.policy-status.expired { + background: #fff2f0; + color: #ff4d4f; +} + +.status-text { + font-size: 22rpx; +} + +/* 保单详情 */ +.policy-details { + margin-bottom: 25rpx; +} + +.detail-item { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10rpx; + font-size: 24rpx; +} + +.detail-item:last-child { + margin-bottom: 0; +} + +.detail-label { + color: #666; +} + +.detail-value { + color: #333; + font-weight: 500; +} + +.detail-value.amount { + color: #ff4757; + font-weight: bold; + font-size: 26rpx; +} + +/* 保单操作 */ +.policy-actions { + display: flex; + gap: 15rpx; + justify-content: flex-end; +} + +.action-btn.small { + padding: 12rpx 24rpx; + font-size: 22rpx; + border-radius: 20rpx; + min-width: 120rpx; +} + +.action-btn.small.primary { + background: #1890ff; + color: white; + border: none; +} + +.action-btn.small.secondary { + background: #52c41a; + color: white; + border: none; +} + +.action-btn.small:not(.primary):not(.secondary) { + background: #f0f0f0; + color: #666; + border: none; +} + +.action-btn.small::after { + border: none; +} + +.action-btn.small:active { + transform: scale(0.95); +} + +/* 空状态 */ +.empty-state { + text-align: center; + padding: 100rpx 40rpx; +} + +.empty-icon { + font-size: 120rpx; + margin-bottom: 30rpx; + opacity: 0.5; +} + +.empty-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 15rpx; + display: block; +} + +.empty-desc { + font-size: 26rpx; + color: #666; + margin-bottom: 40rpx; + display: block; +} + +.empty-btn { + background: #1890ff; + color: white; + border: none; + border-radius: 25rpx; + padding: 20rpx 40rpx; + font-size: 28rpx; + font-weight: bold; +} + +.empty-btn::after { + border: none; +} + +.empty-btn:active { + transform: scale(0.95); +} + +/* 加载更多 */ +.load-more { + text-align: center; + padding: 30rpx; +} + +.loading-text { + font-size: 24rpx; + color: #666; +} + +.load-more-btn { + font-size: 26rpx; + color: #1890ff; + padding: 15rpx 30rpx; + background: white; + border-radius: 25rpx; + display: inline-block; + border: 2rpx solid #1890ff; + transition: all 0.3s; +} + +.load-more-btn:active { + background: #e6f7ff; + transform: scale(0.95); +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .header { + padding: 20rpx; + } + + .policies-list { + padding: 15rpx; + } + + .policy-item { + padding: 20rpx; + } +} + +/* 动画效果 */ +.policy-item { + transition: all 0.3s ease; +} + +.tab-item { + transition: all 0.3s ease; +} + +.action-btn { + transition: all 0.3s ease; +} \ No newline at end of file diff --git a/insurance_mini_program/pages/policy-detail/policy-detail.js b/insurance_mini_program/pages/policy-detail/policy-detail.js new file mode 100644 index 0000000..c701fcf --- /dev/null +++ b/insurance_mini_program/pages/policy-detail/policy-detail.js @@ -0,0 +1,283 @@ +// pages/policy-detail/policy-detail.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 保单ID + policyId: '', + + // 保单信息 + policyInfo: {} + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('保单详情页加载', options) + const { id } = options + if (id) { + this.setData({ policyId: id }) + this.loadPolicyDetail(id) + } else { + wx.showToast({ + title: '保单ID不能为空', + icon: 'none' + }) + setTimeout(() => { + wx.navigateBack() + }, 1500) + } + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('保单详情页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('保单详情页显示') + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('保单详情页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('保单详情页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.loadPolicyDetail(this.data.policyId) + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保单详情', + path: `/pages/policy-detail/policy-detail?id=${this.data.policyId}`, + imageUrl: '/static/images/share-policy-detail.jpg' + } + }, + + /** + * 加载保单详情 + */ + loadPolicyDetail(policyId) { + console.log('加载保单详情:', policyId) + + // 模拟保单详情数据 + const mockPolicyInfo = this.getMockPolicyDetail(policyId) + this.setData({ policyInfo: mockPolicyInfo }) + }, + + /** + * 获取模拟保单详情数据 + */ + getMockPolicyDetail(policyId) { + const mockPolicies = { + '1': { + id: '1', + policyNo: 'POL20240115001', + productName: '综合意外伤害保险', + status: 'active', + statusIcon: '✓', + statusText: '有效', + statusDesc: '您的保单正在有效期内,享受全面保障', + coverageAmount: 50, + premium: 299, + effectiveDate: '2024-01-15', + expiryDate: '2025-01-15', + paymentMethod: '年缴', + insurancePeriod: '1年', + insuredName: '张先生', + idCard: '110101199001011234', + phone: '138****1234', + gender: '男', + birthDate: '1990-01-01', + beneficiary: { + name: '张太太', + relation: '配偶', + idCard: '110101199201011234' + }, + coverage: [ + { + name: '意外身故', + amount: '50万元', + description: '因意外事故导致身故,给付保险金额' + }, + { + name: '意外伤残', + amount: '最高50万元', + description: '因意外事故导致伤残,按伤残等级给付' + }, + { + name: '意外医疗', + amount: '5万元', + description: '因意外事故产生的医疗费用,实报实销' + }, + { + name: '住院津贴', + amount: '200元/天', + description: '因意外事故住院,每日给付津贴' + } + ], + paymentRecords: [ + { + period: '2024年保费', + amount: 299, + status: 'paid', + statusText: '已缴费', + paymentDate: '2024-01-15' + } + ], + claimsRecords: [ + { + type: '意外医疗', + amount: 2500, + status: 'completed', + statusText: '已完成', + date: '2024-01-20' + } + ] + }, + '2': { + id: '2', + policyNo: 'POL20240110002', + productName: '重大疾病保险', + status: 'active', + statusIcon: '✓', + statusText: '有效', + statusDesc: '您的保单正在有效期内,享受重疾保障', + coverageAmount: 30, + premium: 1200, + effectiveDate: '2024-01-10', + expiryDate: '2025-01-10', + paymentMethod: '年缴', + insurancePeriod: '1年', + insuredName: '李女士', + idCard: '110101198501011234', + phone: '139****5678', + gender: '女', + birthDate: '1985-01-01', + beneficiary: { + name: '李女士', + relation: '本人', + idCard: '110101198501011234' + }, + coverage: [ + { + name: '重大疾病', + amount: '30万元', + description: '确诊重大疾病,一次性给付保险金额' + }, + { + name: '轻症疾病', + amount: '6万元', + description: '确诊轻症疾病,给付20%保险金额' + }, + { + name: '身故保障', + amount: '30万元', + description: '因疾病或意外身故,给付保险金额' + } + ], + paymentRecords: [ + { + period: '2024年保费', + amount: 1200, + status: 'paid', + statusText: '已缴费', + paymentDate: '2024-01-10' + } + ], + claimsRecords: [] + } + } + + return mockPolicies[policyId] || mockPolicies['1'] + }, + + /** + * 跳转到续保 + */ + goToRenewal() { + console.log('跳转到续保') + wx.navigateTo({ + url: `/pages/renewal/renewal?policyId=${this.data.policyId}` + }) + }, + + /** + * 跳转到理赔申请 + */ + goToClaim() { + console.log('跳转到理赔申请') + wx.navigateTo({ + url: `/pages/claims/claims?policyId=${this.data.policyId}` + }) + }, + + /** + * 下载保单 + */ + downloadPolicy() { + console.log('下载保单') + wx.showModal({ + title: '下载保单', + content: '是否下载电子保单到本地?', + confirmText: '下载', + success: (res) => { + if (res.confirm) { + wx.showToast({ + title: '保单下载中...', + icon: 'loading' + }) + + // 模拟下载 + setTimeout(() => { + wx.showToast({ + title: '下载成功', + icon: 'success' + }) + }, 2000) + } + } + }) + }, + + /** + * 返回上一页 + */ + goBack() { + console.log('返回上一页') + wx.navigateBack() + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/policy-detail/policy-detail.json b/insurance_mini_program/pages/policy-detail/policy-detail.json new file mode 100644 index 0000000..d182ede --- /dev/null +++ b/insurance_mini_program/pages/policy-detail/policy-detail.json @@ -0,0 +1,7 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "保单详情", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5" +} \ No newline at end of file diff --git a/insurance_mini_program/pages/policy-detail/policy-detail.wxml b/insurance_mini_program/pages/policy-detail/policy-detail.wxml new file mode 100644 index 0000000..6fd0f68 --- /dev/null +++ b/insurance_mini_program/pages/policy-detail/policy-detail.wxml @@ -0,0 +1,199 @@ + + + + + + {{policyInfo.statusIcon}} + + + {{policyInfo.statusText}} + {{policyInfo.statusDesc}} + + + + + + 保单信息 + + + + 保单号 + {{policyInfo.policyNo}} + + + + 产品名称 + {{policyInfo.productName}} + + + + 保险金额 + ¥{{policyInfo.coverageAmount}}万 + + + + 年缴保费 + ¥{{policyInfo.premium}} + + + + 生效日期 + {{policyInfo.effectiveDate}} + + + + 到期日期 + {{policyInfo.expiryDate}} + + + + 缴费方式 + {{policyInfo.paymentMethod}} + + + + 保险期间 + {{policyInfo.insurancePeriod}} + + + + + + + 被保险人信息 + + + + 姓名 + {{policyInfo.insuredName}} + + + + 身份证号 + {{policyInfo.idCard}} + + + + 手机号 + {{policyInfo.phone}} + + + + 性别 + {{policyInfo.gender}} + + + + 出生日期 + {{policyInfo.birthDate}} + + + + + + + 受益人信息 + + + + 受益人姓名 + {{policyInfo.beneficiary.name}} + + + + 关系 + {{policyInfo.beneficiary.relation}} + + + + 身份证号 + {{policyInfo.beneficiary.idCard}} + + + + + + + 保障内容 + + + + + {{item.name}} + {{item.amount}} + + {{item.description}} + + + + + + + 缴费记录 + + + + + {{item.period}} + ¥{{item.amount}} + + + {{item.statusText}} + + {{item.paymentDate}} + + + + + + + 理赔记录 + + + + + {{item.type}} + ¥{{item.amount}} + + + {{item.statusText}} + + {{item.date}} + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/insurance_mini_program/pages/policy-detail/policy-detail.wxss b/insurance_mini_program/pages/policy-detail/policy-detail.wxss new file mode 100644 index 0000000..aeb2d55 --- /dev/null +++ b/insurance_mini_program/pages/policy-detail/policy-detail.wxss @@ -0,0 +1,392 @@ +/* pages/policy-detail/policy-detail.wxss */ +.container { + background: #f5f5f5; + min-height: 100vh; + padding-bottom: 120rpx; +} + +/* 保单状态卡片 */ +.status-card { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 40rpx 30rpx; + display: flex; + align-items: center; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.status-icon { + width: 100rpx; + height: 100rpx; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 30rpx; + font-size: 50rpx; + font-weight: bold; +} + +.status-icon.active { + background: #f6ffed; + color: #52c41a; +} + +.status-icon.expiring { + background: #fff7e6; + color: #d48806; +} + +.status-icon.expired { + background: #fff2f0; + color: #ff4d4f; +} + +.icon-text { + font-size: 50rpx; +} + +.status-content { + flex: 1; +} + +.status-title { + font-size: 36rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; + display: block; +} + +.status-desc { + font-size: 24rpx; + color: #666; + line-height: 1.4; +} + +/* 信息区域 */ +.info-section, +.insured-section, +.beneficiary-section, +.coverage-section, +.payment-section, +.claims-section { + background: white; + margin: 20rpx; + border-radius: 16rpx; + padding: 30rpx; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.section-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 25rpx; + padding-bottom: 15rpx; + border-bottom: 2rpx solid #f0f0f0; +} + +.info-card, +.insured-card, +.beneficiary-card { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.info-item, +.insured-item, +.beneficiary-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 15rpx 0; + border-bottom: 1rpx solid #f5f5f5; +} + +.info-item:last-child, +.insured-item:last-child, +.beneficiary-item:last-child { + border-bottom: none; +} + +.info-label, +.insured-label, +.beneficiary-label { + font-size: 26rpx; + color: #666; + min-width: 150rpx; +} + +.info-value, +.insured-value, +.beneficiary-value { + font-size: 26rpx; + color: #333; + font-weight: 500; + text-align: right; + flex: 1; +} + +.info-value.amount, +.insured-value.amount, +.beneficiary-value.amount { + color: #ff4757; + font-weight: bold; + font-size: 28rpx; +} + +/* 保障内容 */ +.coverage-list { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.coverage-item { + padding: 25rpx; + background: #f8f9fa; + border-radius: 12rpx; + border-left: 4rpx solid #1890ff; +} + +.coverage-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15rpx; +} + +.coverage-name { + font-size: 28rpx; + font-weight: bold; + color: #333; +} + +.coverage-amount { + font-size: 32rpx; + font-weight: bold; + color: #ff4757; +} + +.coverage-desc { + font-size: 24rpx; + color: #666; + line-height: 1.5; +} + +/* 缴费记录 */ +.payment-list { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.payment-item { + display: flex; + align-items: center; + padding: 20rpx; + background: #f8f9fa; + border-radius: 12rpx; +} + +.payment-info { + flex: 1; +} + +.payment-period { + font-size: 26rpx; + color: #333; + margin-bottom: 5rpx; + display: block; +} + +.payment-amount { + font-size: 24rpx; + color: #666; +} + +.payment-status { + padding: 8rpx 16rpx; + border-radius: 20rpx; + font-size: 22rpx; + font-weight: bold; + margin-right: 20rpx; +} + +.payment-status.paid { + background: #f6ffed; + color: #52c41a; +} + +.payment-status.pending { + background: #fff7e6; + color: #d48806; +} + +.payment-status.overdue { + background: #fff2f0; + color: #ff4d4f; +} + +.status-text { + font-size: 22rpx; +} + +.payment-date { + font-size: 22rpx; + color: #999; + min-width: 120rpx; + text-align: right; +} + +/* 理赔记录 */ +.claims-list { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.claim-item { + display: flex; + align-items: center; + padding: 20rpx; + background: #f8f9fa; + border-radius: 12rpx; +} + +.claim-info { + flex: 1; +} + +.claim-type { + font-size: 26rpx; + color: #333; + margin-bottom: 5rpx; + display: block; +} + +.claim-amount { + font-size: 24rpx; + color: #666; +} + +.claim-status { + padding: 8rpx 16rpx; + border-radius: 20rpx; + font-size: 22rpx; + font-weight: bold; + margin-right: 20rpx; +} + +.claim-status.completed { + background: #f6ffed; + color: #52c41a; +} + +.claim-status.processing { + background: #e6f7ff; + color: #1890ff; +} + +.claim-status.rejected { + background: #fff2f0; + color: #ff4d4f; +} + +.claim-date { + font-size: 22rpx; + color: #999; + min-width: 120rpx; + text-align: right; +} + +/* 底部操作栏 */ +.bottom-actions { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: white; + padding: 20rpx 30rpx; + border-top: 1rpx solid #e8e8e8; + display: flex; + gap: 15rpx; + z-index: 100; +} + +.action-btn { + flex: 1; + height: 80rpx; + border-radius: 40rpx; + font-size: 26rpx; + font-weight: bold; + border: none; + transition: all 0.3s; +} + +.action-btn.primary { + background: #1890ff; + color: white; +} + +.action-btn.secondary { + background: #f0f0f0; + color: #666; +} + +.action-btn::after { + border: none; +} + +.action-btn:active { + transform: scale(0.95); +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .status-card, + .info-section, + .insured-section, + .beneficiary-section, + .coverage-section, + .payment-section, + .claims-section { + margin: 15rpx; + padding: 20rpx; + } + + .bottom-actions { + padding: 15rpx 20rpx; + } +} + +/* 动画效果 */ +.coverage-item { + transition: all 0.3s ease; +} + +.coverage-item:hover { + transform: translateY(-2rpx); + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.payment-item { + transition: all 0.3s ease; +} + +.payment-item:active { + background: #e6f7ff; + transform: scale(0.98); +} + +.claim-item { + transition: all 0.3s ease; +} + +.claim-item:active { + background: #e6f7ff; + transform: scale(0.98); +} \ No newline at end of file diff --git a/insurance_mini_program/pages/product-detail/product-detail.js b/insurance_mini_program/pages/product-detail/product-detail.js new file mode 100644 index 0000000..fcb63e9 --- /dev/null +++ b/insurance_mini_program/pages/product-detail/product-detail.js @@ -0,0 +1,426 @@ +// pages/product-detail/product-detail.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 产品ID + productId: '', + + // 当前激活的标签页 + activeTab: 'overview', + + // 产品信息 + productInfo: {}, + + // 相关产品 + relatedProducts: [], + + // 是否已收藏 + isFavorited: false, + + // 是否可以投保 + canApply: false, + + // 加载状态 + loading: false + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('产品详情页加载', options) + const { id } = options + if (id) { + this.setData({ productId: id }) + this.loadProductDetail(id) + } else { + wx.showToast({ + title: '产品ID不能为空', + icon: 'none' + }) + setTimeout(() => { + wx.navigateBack() + }, 1500) + } + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('产品详情页渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('产品详情页显示') + this.checkLoginStatus() + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('产品详情页隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('产品详情页卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.loadProductDetail(this.data.productId) + wx.stopPullDownRefresh() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + const { productInfo } = this.data + return { + title: productInfo.name || '保险产品详情', + path: `/pages/product-detail/product-detail?id=${this.data.productId}`, + imageUrl: productInfo.image || '/static/images/share-product.jpg' + } + }, + + /** + * 加载产品详情 + */ + loadProductDetail(productId) { + this.setData({ loading: true }) + + console.log('加载产品详情:', productId) + + // 模拟API调用 + setTimeout(() => { + const mockProduct = this.getMockProductDetail(productId) + this.setData({ + productInfo: mockProduct, + relatedProducts: this.getMockRelatedProducts(), + loading: false + }) + this.checkFavoritedStatus() + }, 1000) + }, + + /** + * 获取模拟产品详情数据 + */ + getMockProductDetail(productId) { + const mockProducts = { + '1': { + id: '1', + name: '综合意外伤害保险', + subtitle: '全面保障,安心出行', + image: '/static/images/product-1.jpg', + isHot: true, + minPremium: 99, + priceDesc: '年缴保费,保障一年', + description: '本产品为综合意外伤害保险,提供全面的意外伤害保障,包括意外身故、意外伤残、意外医疗等保障内容,让您出行更安心。', + features: [ + { icon: '🛡️', text: '全面保障' }, + { icon: '⚡', text: '快速理赔' }, + { icon: '💰', text: '性价比高' }, + { icon: '📱', text: '在线投保' } + ], + targetGroup: [ + '18-65周岁身体健康者', + '经常出差或外出人员', + '从事高风险职业者', + '家庭经济支柱' + ], + highlights: [ + { + icon: '🛡️', + title: '保障全面', + description: '涵盖意外身故、伤残、医疗等多种保障,全方位保护您的安全' + }, + { + icon: '⚡', + title: '理赔快速', + description: '7x24小时理赔服务,材料齐全3个工作日内完成理赔' + }, + { + icon: '💰', + title: '性价比高', + description: '保费低廉,保障全面,是您最经济实惠的选择' + } + ], + coverage: [ + { + name: '意外身故保险金', + amount: '50万元', + description: '被保险人因意外伤害导致身故,给付意外身故保险金', + conditions: '意外伤害事故发生之日起180日内身故' + }, + { + name: '意外伤残保险金', + amount: '最高50万元', + description: '被保险人因意外伤害导致伤残,按伤残等级给付保险金', + conditions: '意外伤害事故发生之日起180日内伤残' + }, + { + name: '意外医疗保险金', + amount: '5万元', + description: '被保险人因意外伤害产生的医疗费用,按比例报销', + conditions: '免赔额100元,赔付比例90%' + } + ], + terms: [ + { + title: '保险期间', + content: '本保险合同的保险期间为一年,自保险单载明的保险期间开始日零时起至保险期间届满日二十四时止。' + }, + { + title: '等待期', + content: '本保险合同无等待期,自保险期间开始日零时起即承担保险责任。' + }, + { + title: '免赔额', + content: '意外医疗保险金免赔额为100元,超出部分按90%比例赔付。' + } + ], + notices: [ + '请仔细阅读保险条款,特别是责任免除条款', + '投保时请如实告知健康状况,否则可能影响理赔', + '保险期间内可随时退保,按日计算退还保费', + '理赔时需提供相关证明材料', + '如有疑问请及时联系客服' + ] + }, + '2': { + id: '2', + name: '重大疾病保险', + subtitle: '重疾保障,守护健康', + image: '/static/images/product-2.jpg', + isHot: false, + minPremium: 299, + priceDesc: '年缴保费,保障终身', + description: '本产品为重大疾病保险,提供重大疾病保障,包括恶性肿瘤、急性心肌梗塞、脑中风后遗症等重大疾病保障。', + features: [ + { icon: '🏥', text: '重疾保障' }, + { icon: '💊', text: '医疗费用' }, + { icon: '🔄', text: '多次赔付' }, + { icon: '👨‍👩‍👧‍👦', text: '家庭保障' } + ], + targetGroup: [ + '18-55周岁身体健康者', + '有家族病史者', + '关注健康保障者', + '家庭经济支柱' + ], + highlights: [ + { + icon: '🏥', + title: '重疾保障', + description: '涵盖100种重大疾病,保障范围广泛,让您安心无忧' + }, + { + icon: '💊', + title: '医疗费用', + description: '提供高额医疗费用保障,减轻家庭经济负担' + }, + { + icon: '🔄', + title: '多次赔付', + description: '部分疾病可多次赔付,保障更全面' + } + ], + coverage: [ + { + name: '重大疾病保险金', + amount: '30万元', + description: '被保险人确诊重大疾病,给付重大疾病保险金', + conditions: '等待期90天,确诊即赔' + }, + { + name: '轻症疾病保险金', + amount: '6万元', + description: '被保险人确诊轻症疾病,给付轻症疾病保险金', + conditions: '等待期90天,最多赔付3次' + }, + { + name: '身故保险金', + amount: '30万元', + description: '被保险人身故,给付身故保险金', + conditions: '等待期90天' + } + ], + terms: [ + { + title: '保险期间', + content: '本保险合同的保险期间为终身,自保险单载明的保险期间开始日零时起至被保险人身故时止。' + }, + { + title: '等待期', + content: '本保险合同的等待期为90天,等待期内因疾病导致保险事故,不承担保险责任。' + }, + { + title: '缴费期间', + content: '缴费期间为20年,投保人可选择年缴或月缴。' + } + ], + notices: [ + '请仔细阅读保险条款,特别是责任免除条款', + '投保时请如实告知健康状况,否则可能影响理赔', + '等待期内因疾病导致保险事故,不承担保险责任', + '理赔时需提供医院诊断证明', + '如有疑问请及时联系客服' + ] + } + } + + return mockProducts[productId] || mockProducts['1'] + }, + + /** + * 获取模拟相关产品数据 + */ + getMockRelatedProducts() { + return [ + { + id: '2', + name: '重大疾病保险', + image: '/static/images/product-2.jpg', + minPremium: 299 + }, + { + id: '3', + name: '定期寿险', + image: '/static/images/product-3.jpg', + minPremium: 199 + }, + { + id: '4', + name: '医疗保险', + image: '/static/images/product-4.jpg', + minPremium: 399 + } + ] + }, + + /** + * 检查登录状态 + */ + checkLoginStatus() { + const token = wx.getStorageSync('token') + this.setData({ + canApply: !!token + }) + }, + + /** + * 检查收藏状态 + */ + checkFavoritedStatus() { + const favorites = wx.getStorageSync('favorites') || [] + const isFavorited = favorites.includes(this.data.productId) + this.setData({ isFavorited }) + }, + + /** + * 切换标签页 + */ + switchTab(e) { + const tab = e.currentTarget.dataset.tab + console.log('切换标签页:', tab) + this.setData({ activeTab: tab }) + }, + + /** + * 添加到收藏 + */ + addToFavorites() { + const { productId, isFavorited } = this.data + let favorites = wx.getStorageSync('favorites') || [] + + if (isFavorited) { + // 取消收藏 + favorites = favorites.filter(id => id !== productId) + wx.showToast({ + title: '已取消收藏', + icon: 'success' + }) + } else { + // 添加收藏 + favorites.push(productId) + wx.showToast({ + title: '已添加到收藏', + icon: 'success' + }) + } + + wx.setStorageSync('favorites', favorites) + this.setData({ isFavorited: !isFavorited }) + }, + + /** + * 跳转到咨询页面 + */ + goToConsultation() { + console.log('跳转到咨询页面') + wx.navigateTo({ + url: '/pages/consultation/consultation' + }) + }, + + /** + * 跳转到投保页面 + */ + goToApplication() { + const { canApply, productId } = this.data + + if (!canApply) { + wx.showModal({ + title: '提示', + content: '请先登录后再进行投保', + confirmText: '去登录', + success: (res) => { + if (res.confirm) { + wx.navigateTo({ + url: '/pages/login/login' + }) + } + } + }) + return + } + + console.log('跳转到投保页面:', productId) + wx.navigateTo({ + url: `/pages/application/application?productId=${productId}` + }) + }, + + /** + * 跳转到其他产品详情页 + */ + goToProductDetail(e) { + const productId = e.currentTarget.dataset.id + console.log('跳转到产品详情页:', productId) + wx.redirectTo({ + url: `/pages/product-detail/product-detail?id=${productId}` + }) + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/product-detail/product-detail.json b/insurance_mini_program/pages/product-detail/product-detail.json new file mode 100644 index 0000000..e756925 --- /dev/null +++ b/insurance_mini_program/pages/product-detail/product-detail.json @@ -0,0 +1,8 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "产品详情", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5", + "onReachBottomDistance": 50 +} \ No newline at end of file diff --git a/insurance_mini_program/pages/product-detail/product-detail.wxml b/insurance_mini_program/pages/product-detail/product-detail.wxml new file mode 100644 index 0000000..a45d4d1 --- /dev/null +++ b/insurance_mini_program/pages/product-detail/product-detail.wxml @@ -0,0 +1,177 @@ + + + + + + + 热门 + + + + {{productInfo.name}} + {{productInfo.subtitle}} + + + + ¥ + {{productInfo.minPremium}} + + + {{productInfo.priceDesc}} + + + + + {{item.icon}} + {{item.text}} + + + + + + + + + 产品概述 + + + 保障内容 + + + 条款说明 + + + + + + + 产品简介 + {{productInfo.description}} + + + + 适用人群 + + + + {{item}} + + + + + + 产品特色 + + + {{item.icon}} + + {{item.title}} + {{item.description}} + + + + + + + + + + + + {{item.name}} + {{item.amount}} + + {{item.description}} + + 保障条件: + {{item.conditions}} + + + + + + + + + + {{item.title}} + {{item.content}} + + + + + + + 投保须知 + + + {{index + 1}} + {{item}} + + + + + + + 相关产品推荐 + + + + + + {{item.name}} + ¥{{item.minPremium}}起 + + + + + + + + + + + + + + + + + + + + + + 加载中... + + \ No newline at end of file diff --git a/insurance_mini_program/pages/product-detail/product-detail.wxss b/insurance_mini_program/pages/product-detail/product-detail.wxss new file mode 100644 index 0000000..c493001 --- /dev/null +++ b/insurance_mini_program/pages/product-detail/product-detail.wxss @@ -0,0 +1,575 @@ +/* pages/product-detail/product-detail.wxss */ +.container { + background: #f5f5f5; + min-height: 100vh; + padding-bottom: 120rpx; +} + +/* 产品头部信息 */ +.product-header { + background: white; + padding: 30rpx; + margin-bottom: 20rpx; +} + +.product-image { + position: relative; + width: 100%; + height: 300rpx; + margin-bottom: 30rpx; + border-radius: 16rpx; + overflow: hidden; +} + +.product-img { + width: 100%; + height: 100%; +} + +.product-tag { + position: absolute; + top: 20rpx; + right: 20rpx; + background: #ff4757; + color: white; + font-size: 22rpx; + padding: 8rpx 16rpx; + border-radius: 20rpx; +} + +.product-info { + padding: 0 10rpx; +} + +.product-title { + font-size: 36rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; + line-height: 1.4; +} + +.product-subtitle { + font-size: 26rpx; + color: #666; + margin-bottom: 20rpx; + line-height: 1.4; +} + +.price-section { + margin-bottom: 30rpx; +} + +.price-main { + display: flex; + align-items: baseline; + margin-bottom: 10rpx; +} + +.currency { + font-size: 28rpx; + color: #ff4757; + font-weight: bold; +} + +.price { + font-size: 48rpx; + color: #ff4757; + font-weight: bold; + margin: 0 5rpx; +} + +.price-unit { + font-size: 24rpx; + color: #999; +} + +.price-desc { + font-size: 22rpx; + color: #999; +} + +.product-features { + display: flex; + flex-wrap: wrap; + gap: 20rpx; +} + +.feature-item { + display: flex; + align-items: center; + background: #f8f9fa; + padding: 12rpx 20rpx; + border-radius: 20rpx; + font-size: 24rpx; + color: #666; +} + +.feature-icon { + margin-right: 8rpx; + font-size: 26rpx; +} + +.feature-text { + font-size: 24rpx; +} + +/* 详情标签页 */ +.detail-tabs { + display: flex; + background: white; + margin-bottom: 20rpx; + border-bottom: 1rpx solid #e8e8e8; +} + +.tab-item { + flex: 1; + text-align: center; + padding: 30rpx 0; + font-size: 28rpx; + color: #666; + position: relative; + transition: all 0.3s; +} + +.tab-item.active { + color: #1890ff; + font-weight: bold; +} + +.tab-item.active::after { + content: ''; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 60rpx; + height: 4rpx; + background: #1890ff; + border-radius: 2rpx; +} + +/* 标签页内容 */ +.tab-content { + background: white; + padding: 30rpx; + margin-bottom: 20rpx; +} + +.overview-section { + margin-bottom: 40rpx; +} + +.overview-section:last-child { + margin-bottom: 0; +} + +.section-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 20rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid #f0f0f0; +} + +.section-content { + font-size: 28rpx; + color: #666; + line-height: 1.6; +} + +.target-group { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.group-item { + display: flex; + align-items: center; + font-size: 26rpx; + color: #666; +} + +.group-icon { + color: #52c41a; + margin-right: 15rpx; + font-size: 24rpx; +} + +.group-text { + flex: 1; +} + +.highlights { + display: flex; + flex-direction: column; + gap: 25rpx; +} + +.highlight-item { + display: flex; + align-items: flex-start; + padding: 20rpx; + background: #f8f9fa; + border-radius: 12rpx; +} + +.highlight-icon { + font-size: 40rpx; + margin-right: 20rpx; + margin-top: 5rpx; +} + +.highlight-content { + flex: 1; +} + +.highlight-title { + font-size: 28rpx; + font-weight: bold; + color: #333; + margin-bottom: 8rpx; + display: block; +} + +.highlight-desc { + font-size: 24rpx; + color: #666; + line-height: 1.5; +} + +/* 保障内容 */ +.coverage-section { + display: flex; + flex-direction: column; + gap: 25rpx; +} + +.coverage-item { + padding: 25rpx; + background: #f8f9fa; + border-radius: 12rpx; + border-left: 4rpx solid #1890ff; +} + +.coverage-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15rpx; +} + +.coverage-name { + font-size: 28rpx; + font-weight: bold; + color: #333; +} + +.coverage-amount { + font-size: 32rpx; + font-weight: bold; + color: #ff4757; +} + +.coverage-desc { + font-size: 26rpx; + color: #666; + line-height: 1.5; + margin-bottom: 10rpx; + display: block; +} + +.coverage-conditions { + font-size: 24rpx; + color: #999; +} + +.condition-label { + font-weight: bold; +} + +.condition-text { + margin-left: 10rpx; +} + +/* 条款说明 */ +.terms-section { + display: flex; + flex-direction: column; + gap: 25rpx; +} + +.terms-item { + padding: 25rpx; + background: #f8f9fa; + border-radius: 12rpx; +} + +.terms-title { + font-size: 28rpx; + font-weight: bold; + color: #333; + margin-bottom: 15rpx; +} + +.terms-content { + font-size: 26rpx; + color: #666; + line-height: 1.6; +} + +/* 投保须知 */ +.notice-section { + background: white; + padding: 30rpx; + margin-bottom: 20rpx; +} + +.notice-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 25rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid #f0f0f0; +} + +.notice-list { + display: flex; + flex-direction: column; + gap: 15rpx; +} + +.notice-item { + display: flex; + align-items: flex-start; + font-size: 26rpx; + color: #666; + line-height: 1.5; +} + +.notice-number { + width: 40rpx; + height: 40rpx; + background: #1890ff; + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 22rpx; + font-weight: bold; + margin-right: 20rpx; + flex-shrink: 0; + margin-top: 5rpx; +} + +.notice-text { + flex: 1; +} + +/* 相关产品推荐 */ +.related-products { + background: white; + padding: 30rpx; + margin-bottom: 20rpx; +} + +.product-scroll { + white-space: nowrap; +} + +.product-list { + display: flex; + gap: 20rpx; + padding: 10rpx 0; +} + +.related-product-item { + width: 200rpx; + background: #f8f9fa; + border-radius: 12rpx; + overflow: hidden; + flex-shrink: 0; +} + +.related-product-img { + width: 100%; + height: 120rpx; +} + +.related-product-info { + padding: 15rpx; +} + +.related-product-name { + font-size: 24rpx; + color: #333; + margin-bottom: 8rpx; + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.related-product-price { + font-size: 22rpx; + color: #ff4757; + font-weight: bold; +} + +/* 底部操作栏 */ +.bottom-actions { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: white; + padding: 20rpx 30rpx; + border-top: 1rpx solid #e8e8e8; + display: flex; + align-items: center; + gap: 20rpx; + z-index: 100; +} + +.action-left { + display: flex; + gap: 15rpx; +} + +.action-btn { + display: flex; + flex-direction: column; + align-items: center; + padding: 15rpx 20rpx; + background: #f8f9fa; + border: none; + border-radius: 12rpx; + font-size: 20rpx; + color: #666; + min-width: 80rpx; +} + +.action-btn::after { + border: none; +} + +.btn-icon { + font-size: 32rpx; + margin-bottom: 5rpx; +} + +.btn-text { + font-size: 20rpx; +} + +.apply-btn { + flex: 1; + height: 80rpx; + border-radius: 40rpx; + font-size: 32rpx; + font-weight: bold; + border: none; + transition: all 0.3s; +} + +.apply-btn.active { + background: #1890ff; + color: white; +} + +.apply-btn.disabled { + background: #f0f0f0; + color: #ccc; +} + +.apply-btn::after { + border: none; +} + +/* 加载状态 */ +.loading-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.loading-content { + background: white; + padding: 40rpx; + border-radius: 16rpx; + display: flex; + flex-direction: column; + align-items: center; + gap: 20rpx; +} + +.loading-spinner { + width: 60rpx; + height: 60rpx; + border: 4rpx solid #f0f0f0; + border-top: 4rpx solid #1890ff; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading-text { + font-size: 28rpx; + color: #666; +} + +/* 响应式设计 */ +@media (max-width: 750rpx) { + .product-header { + padding: 20rpx; + } + + .product-image { + height: 250rpx; + } + + .tab-content { + padding: 20rpx; + } + + .bottom-actions { + padding: 15rpx 20rpx; + } +} + +/* 动画效果 */ +.tab-item { + transition: all 0.3s ease; +} + +.coverage-item { + transition: all 0.3s ease; +} + +.coverage-item:hover { + transform: translateY(-2rpx); + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); +} + +.related-product-item:active { + transform: scale(0.95); +} + +.action-btn:active { + transform: scale(0.95); +} \ No newline at end of file diff --git a/insurance_mini_program/pages/products/products.js b/insurance_mini_program/pages/products/products.js new file mode 100644 index 0000000..3de2afe --- /dev/null +++ b/insurance_mini_program/pages/products/products.js @@ -0,0 +1,346 @@ +// pages/products/products.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + // 搜索关键词 + searchKeyword: '', + + // 产品分类 + categories: [ + { id: 'all', name: '全部' }, + { id: 'life', name: '寿险' }, + { id: 'health', name: '健康险' }, + { id: 'accident', name: '意外险' }, + { id: 'vehicle', name: '车险' }, + { id: 'property', name: '财产险' }, + { id: 'travel', name: '旅行险' }, + { id: 'pet', name: '宠物险' } + ], + + // 当前选中的分类 + selectedCategory: 'all', + + // 排序选项 + sortOptions: [ + { value: 'default', label: '默认排序' }, + { value: 'price_asc', label: '价格从低到高' }, + { value: 'price_desc', label: '价格从高到低' }, + { value: 'popular', label: '热门推荐' } + ], + + // 当前排序方式 + sortBy: 'default', + + // 视图模式:list 或 grid + viewMode: 'list', + + // 产品列表 + productList: [], + + // 分页信息 + currentPage: 1, + pageSize: 10, + totalCount: 0, + hasMore: true, + + // 加载状态 + loading: false + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + console.log('产品页面加载完成') + this.loadProducts() + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + console.log('产品页面渲染完成') + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + console.log('产品页面显示') + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + console.log('产品页面隐藏') + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + console.log('产品页面卸载') + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + console.log('下拉刷新') + this.refreshProducts() + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + console.log('上拉触底') + if (this.data.hasMore && !this.data.loading) { + this.loadMore() + } + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + return { + title: '保险产品 - 专业安全的保险平台', + path: '/pages/products/products', + imageUrl: '/static/images/share-products.jpg' + } + }, + + /** + * 搜索输入事件 + */ + onSearchInput(e) { + this.setData({ + searchKeyword: e.detail.value + }) + }, + + /** + * 执行搜索 + */ + onSearch() { + console.log('执行搜索:', this.data.searchKeyword) + this.refreshProducts() + }, + + /** + * 分类切换 + */ + onCategoryChange(e) { + const category = e.currentTarget.dataset.category + console.log('切换分类:', category) + this.setData({ + selectedCategory: category + }) + this.refreshProducts() + }, + + /** + * 排序切换 + */ + onSortChange(e) { + const sort = e.currentTarget.dataset.sort + console.log('切换排序:', sort) + this.setData({ + sortBy: sort + }) + this.refreshProducts() + }, + + /** + * 视图模式切换 + */ + onViewModeChange(e) { + const mode = e.currentTarget.dataset.mode + console.log('切换视图模式:', mode) + this.setData({ + viewMode: mode + }) + }, + + /** + * 加载产品数据 + */ + loadProducts() { + this.setData({ loading: true }) + + // 模拟API调用 + setTimeout(() => { + const mockProducts = this.getMockProducts() + this.setData({ + productList: mockProducts, + totalCount: mockProducts.length, + hasMore: false, + loading: false + }) + }, 1000) + }, + + /** + * 刷新产品数据 + */ + refreshProducts() { + this.setData({ + currentPage: 1, + productList: [], + hasMore: true + }) + this.loadProducts() + }, + + /** + * 加载更多产品 + */ + loadMore() { + if (this.data.loading || !this.data.hasMore) return + + this.setData({ loading: true }) + + // 模拟加载更多 + setTimeout(() => { + const moreProducts = this.getMockProducts() + this.setData({ + productList: [...this.data.productList, ...moreProducts], + currentPage: this.data.currentPage + 1, + hasMore: false, + loading: false + }) + }, 1000) + }, + + /** + * 获取模拟产品数据 + */ + getMockProducts() { + const allProducts = [ + { + id: 1, + name: '综合意外险', + description: '全面保障意外伤害,保费低廉,保障全面', + min_premium: 99, + icon: '🛡️', + category: 'accident', + tags: ['热门', '性价比高', '保障全面'] + }, + { + id: 2, + name: '重疾保险', + description: '重大疾病保障,安心无忧,覆盖多种疾病', + min_premium: 299, + icon: '🏥', + category: 'health', + tags: ['保障全面', '疾病覆盖', '长期保障'] + }, + { + id: 3, + name: '车险', + description: '车辆全面保障,理赔快速,服务专业', + min_premium: 1999, + icon: '🚗', + category: 'vehicle', + tags: ['必买', '理赔快', '服务好'] + }, + { + id: 4, + name: '旅行险', + description: '出行安全保障,全球覆盖,24小时服务', + min_premium: 59, + icon: '✈️', + category: 'travel', + tags: ['短期', '全球', '24小时'] + }, + { + id: 5, + name: '寿险', + description: '终身保障,家庭责任,财富传承', + min_premium: 599, + icon: '👨‍👩‍👧‍👦', + category: 'life', + tags: ['终身', '家庭', '传承'] + }, + { + id: 6, + name: '财产险', + description: '家庭财产保障,火灾水灾全覆盖', + min_premium: 199, + icon: '🏠', + category: 'property', + tags: ['家庭', '财产', '全面'] + }, + { + id: 7, + name: '宠物险', + description: '宠物医疗保障,爱宠健康无忧', + min_premium: 89, + icon: '🐕', + category: 'pet', + tags: ['宠物', '医疗', '贴心'] + }, + { + id: 8, + name: '高端医疗险', + description: '高端医疗服务,VIP待遇,全球就医', + min_premium: 1999, + icon: '💎', + category: 'health', + tags: ['高端', 'VIP', '全球'] + } + ] + + // 根据分类筛选 + let filteredProducts = allProducts + if (this.data.selectedCategory !== 'all') { + filteredProducts = allProducts.filter(product => + product.category === this.data.selectedCategory + ) + } + + // 根据搜索关键词筛选 + if (this.data.searchKeyword) { + const keyword = this.data.searchKeyword.toLowerCase() + filteredProducts = filteredProducts.filter(product => + product.name.toLowerCase().includes(keyword) || + product.description.toLowerCase().includes(keyword) + ) + } + + // 根据排序方式排序 + switch (this.data.sortBy) { + case 'price_asc': + filteredProducts.sort((a, b) => a.min_premium - b.min_premium) + break + case 'price_desc': + filteredProducts.sort((a, b) => b.min_premium - a.min_premium) + break + case 'popular': + // 模拟热门排序 + filteredProducts.sort((a, b) => b.id - a.id) + break + default: + // 默认排序 + break + } + + return filteredProducts + }, + + /** + * 跳转到产品详情页 + */ + goToProductDetail(e) { + const productId = e.currentTarget.dataset.id + console.log('跳转到产品详情页:', productId) + wx.navigateTo({ + url: `/pages/product-detail/product-detail?id=${productId}` + }) + } +}) \ No newline at end of file diff --git a/insurance_mini_program/pages/products/products.json b/insurance_mini_program/pages/products/products.json new file mode 100644 index 0000000..0f63d61 --- /dev/null +++ b/insurance_mini_program/pages/products/products.json @@ -0,0 +1,8 @@ +{ + "usingComponents": {}, + "navigationBarTitleText": "保险产品", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark", + "backgroundColor": "#f5f5f5", + "onReachBottomDistance": 50 +} \ No newline at end of file diff --git a/insurance_mini_program/pages/products/products.wxml b/insurance_mini_program/pages/products/products.wxml new file mode 100644 index 0000000..1487541 --- /dev/null +++ b/insurance_mini_program/pages/products/products.wxml @@ -0,0 +1,152 @@ + + + + + + + 🔍 + + + + + + + + + {{item.name}} + + + + + + + + + + {{item.label}} + + + + + + + + 共 {{totalCount}} 个产品 + + + 列表 + + + 网格 + + + + + + + + {{item.icon}} + + {{item.name}} + {{item.description}} + + {{item}} + + + 起保费: + ¥{{item.min_premium}} + /年 + + + + + + + + + + + + + {{item.icon}} + + {{item.name}} + {{item.description}} + + {{item}} + + + 起保费: + ¥{{item.min_premium}} + + + + + + + + + + 加载中... + + + + + 📦 + 暂无产品 + 请尝试其他筛选条件 + + + + + + + + \ No newline at end of file diff --git a/insurance_mini_program/pages/products/products.wxss b/insurance_mini_program/pages/products/products.wxss new file mode 100644 index 0000000..a56c579 --- /dev/null +++ b/insurance_mini_program/pages/products/products.wxss @@ -0,0 +1,367 @@ +/* pages/products/products.wxss */ +.container { + background-color: #f5f5f5; + min-height: 100vh; +} + +/* 搜索栏 */ +.search-bar { + background: #fff; + padding: 20rpx 30rpx; + border-bottom: 1px solid #f0f0f0; +} + +.search-input-wrapper { + position: relative; + display: flex; + align-items: center; + background: #f8f8f8; + border-radius: 25rpx; + padding: 0 20rpx; +} + +.search-input { + flex: 1; + height: 70rpx; + font-size: 28rpx; + padding: 0 20rpx; +} + +.search-icon { + font-size: 32rpx; + color: #999; + padding: 10rpx; +} + +/* 分类筛选 */ +.filter-section { + background: #fff; + padding: 20rpx 0; + border-bottom: 1px solid #f0f0f0; +} + +.category-scroll { + white-space: nowrap; +} + +.category-list { + display: flex; + padding: 0 30rpx; +} + +.category-item { + display: inline-block; + padding: 15rpx 30rpx; + margin-right: 20rpx; + background: #f8f8f8; + border-radius: 25rpx; + font-size: 26rpx; + color: #666; + transition: all 0.3s; +} + +.category-item.active { + background: #1890ff; + color: #fff; +} + +.category-text { + font-size: 26rpx; +} + +/* 排序选项 */ +.sort-section { + background: #fff; + padding: 20rpx 30rpx; + border-bottom: 1px solid #f0f0f0; +} + +.sort-options { + display: flex; + justify-content: space-around; +} + +.sort-item { + padding: 15rpx 30rpx; + border-radius: 20rpx; + font-size: 26rpx; + color: #666; + background: #f8f8f8; + transition: all 0.3s; +} + +.sort-item.active { + background: #e6f7ff; + color: #1890ff; +} + +.sort-text { + font-size: 26rpx; +} + +/* 产品区域 */ +.products-section { + padding: 30rpx; +} + +.products-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30rpx; +} + +.products-count { + font-size: 28rpx; + color: #666; +} + +.view-toggle { + display: flex; + background: #f8f8f8; + border-radius: 20rpx; + overflow: hidden; +} + +.toggle-item { + padding: 10rpx 20rpx; + font-size: 24rpx; + color: #666; + background: transparent; + transition: all 0.3s; +} + +.toggle-item.active { + background: #1890ff; + color: #fff; +} + +/* 列表视图 */ +.product-list { + display: flex; + flex-direction: column; + gap: 20rpx; +} + +.product-item-list { + display: flex; + background: #fff; + border-radius: 12rpx; + padding: 30rpx; + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); + align-items: center; +} + +.product-icon-large { + font-size: 80rpx; + width: 120rpx; + height: 120rpx; + margin-right: 30rpx; + display: flex; + align-items: center; + justify-content: center; + background: #f0f8ff; + border-radius: 12rpx; +} + +.product-info { + flex: 1; +} + +.product-name { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; + display: block; +} + +.product-desc { + font-size: 26rpx; + color: #666; + margin-bottom: 15rpx; + display: block; + line-height: 1.4; +} + +.product-tags { + display: flex; + flex-wrap: wrap; + gap: 10rpx; + margin-bottom: 15rpx; +} + +.product-tag { + background: #e6f7ff; + color: #1890ff; + font-size: 20rpx; + padding: 5rpx 15rpx; + border-radius: 15rpx; +} + +.product-price-row { + display: flex; + align-items: baseline; +} + +.price-label { + font-size: 24rpx; + color: #999; + margin-right: 10rpx; +} + +.price-value { + font-size: 36rpx; + color: #ff6b35; + font-weight: bold; +} + +.price-unit { + font-size: 24rpx; + color: #999; + margin-left: 5rpx; +} + +.product-actions { + margin-left: 20rpx; +} + +.btn-apply { + background: #1890ff; + color: #fff; + border: none; + border-radius: 20rpx; + font-size: 24rpx; + padding: 15rpx 30rpx; +} + +/* 网格视图 */ +.product-grid { + display: flex; + flex-wrap: wrap; + gap: 20rpx; +} + +.product-item-grid { + width: calc(50% - 10rpx); +} + +.product-card { + background: #fff; + border-radius: 12rpx; + padding: 30rpx; + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); + text-align: center; +} + +.product-icon { + font-size: 60rpx; + width: 100rpx; + height: 100rpx; + margin: 0 auto 20rpx; + display: flex; + align-items: center; + justify-content: center; + background: #f0f8ff; + border-radius: 50%; +} + +.product-name { + font-size: 28rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; + display: block; +} + +.product-desc { + font-size: 24rpx; + color: #666; + margin-bottom: 15rpx; + display: block; + line-height: 1.4; +} + +.product-tags { + display: flex; + flex-wrap: wrap; + gap: 8rpx; + justify-content: center; + margin-bottom: 15rpx; +} + +.product-tag { + background: #e6f7ff; + color: #1890ff; + font-size: 18rpx; + padding: 4rpx 12rpx; + border-radius: 12rpx; +} + +.product-price { + display: flex; + align-items: baseline; + justify-content: center; + margin-bottom: 20rpx; +} + +.price-label { + font-size: 22rpx; + color: #999; + margin-right: 8rpx; +} + +.price-value { + font-size: 32rpx; + color: #ff6b35; + font-weight: bold; +} + +/* 加载状态 */ +.loading { + text-align: center; + padding: 60rpx; + color: #999; + font-size: 28rpx; +} + +/* 空状态 */ +.empty-state { + text-align: center; + padding: 100rpx 30rpx; + color: #999; +} + +.empty-icon { + font-size: 120rpx; + margin-bottom: 30rpx; + opacity: 0.5; +} + +.empty-text { + font-size: 32rpx; + color: #666; + margin-bottom: 15rpx; + display: block; +} + +.empty-desc { + font-size: 26rpx; + color: #999; + display: block; +} + +/* 加载更多 */ +.load-more { + text-align: center; + padding: 40rpx; +} + +.btn-load-more { + background: #f8f8f8; + color: #666; + border: 1px solid #e8e8e8; + border-radius: 25rpx; + font-size: 26rpx; + padding: 20rpx 60rpx; +} \ No newline at end of file diff --git a/insurance_mini_program/sitemap.json b/insurance_mini_program/sitemap.json new file mode 100644 index 0000000..223de2c --- /dev/null +++ b/insurance_mini_program/sitemap.json @@ -0,0 +1,9 @@ +{ + "desc": "保险小程序的索引配置文件", + "rules": [ + { + "action": "allow", + "page": "*" + } + ] +} \ No newline at end of file diff --git a/insurance_mini_program/src/pages/index/index.vue b/insurance_mini_program/src/pages/index/index.vue index 83854e6..74a5190 100644 --- a/insurance_mini_program/src/pages/index/index.vue +++ b/insurance_mini_program/src/pages/index/index.vue @@ -1,28 +1,27 @@ \ No newline at end of file diff --git a/mini_program/farm-monitor-dashboard/API_INTEGRATION.md b/mini_program/farm-monitor-dashboard/API_INTEGRATION.md new file mode 100644 index 0000000..a19fa00 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/API_INTEGRATION.md @@ -0,0 +1,241 @@ +# 智能设备API接口集成文档 + +## 概述 +本文档描述了智慧养殖小程序中智能设备管理系统的API接口集成情况。 + +## 基础配置 +- **API基础地址**: `http://localhost:5350` +- **认证方式**: Bearer Token (存储在localStorage中) +- **请求超时**: 10秒 +- **内容类型**: application/json + +## 智能设备接口 + +### 1. 智能项圈管理 (`/api/smart-devices/collars`) + +#### 获取项圈设备列表 +- **接口**: `GET /api/smart-devices/collars` +- **参数**: + - `page` (可选): 页码 + - `limit` (可选): 每页数量 + - `status` (可选): 设备状态筛选 +- **返回**: 项圈设备列表数据 + +#### 绑定项圈设备 +- **接口**: `POST /api/smart-devices/collars/bind` +- **参数**: + ```json + { + "collarId": "string", + "animalId": "string" + } + ``` + +#### 解绑项圈设备 +- **接口**: `POST /api/smart-devices/collars/unbind` +- **参数**: + ```json + { + "collarId": "string" + } + ``` + +### 2. 智能耳标管理 (`/api/smart-devices/eartags`) + +#### 获取耳标设备列表 +- **接口**: `GET /api/smart-devices/eartags` +- **参数**: + - `page` (可选): 页码 + - `limit` (可选): 每页数量 + - `status` (可选): 设备状态筛选 +- **返回**: 耳标设备列表数据 + +#### 绑定耳标设备 +- **接口**: `POST /api/smart-devices/eartags/bind` +- **参数**: + ```json + { + "earTagId": "string", + "animalId": "string" + } + ``` + +#### 解绑耳标设备 +- **接口**: `POST /api/smart-devices/eartags/unbind` +- **参数**: + ```json + { + "earTagId": "string" + } + ``` + +#### 获取耳标设备详情 +- **接口**: `GET /api/smart-devices/eartags/{earTagId}` +- **返回**: 耳标设备详细信息 + +#### 更新耳标设备信息 +- **接口**: `PUT /api/smart-devices/eartags/{earTagId}` +- **参数**: 设备更新数据 + +#### 删除耳标设备 +- **接口**: `DELETE /api/smart-devices/eartags/{earTagId}` + +### 3. 智能脚环管理 (`/api/smart-devices/anklets`) + +#### 获取脚环设备列表 +- **接口**: `GET /api/smart-devices/anklets` +- **参数**: + - `page` (可选): 页码 + - `limit` (可选): 每页数量 + - `status` (可选): 设备状态筛选 +- **返回**: 脚环设备列表数据 + +#### 绑定脚环设备 +- **接口**: `POST /api/smart-devices/anklets/bind` +- **参数**: + ```json + { + "ankleId": "string", + "animalId": "string" + } + ``` + +#### 解绑脚环设备 +- **接口**: `POST /api/smart-devices/anklets/unbind` +- **参数**: + ```json + { + "ankleId": "string" + } + ``` + +### 4. 智能主机管理 (`/api/smart-devices/hosts`) + +#### 获取主机设备列表 +- **接口**: `GET /api/smart-devices/hosts` +- **参数**: + - `page` (可选): 页码 + - `limit` (可选): 每页数量 + - `status` (可选): 设备状态筛选 +- **返回**: 主机设备列表数据 + +#### 重启主机设备 +- **接口**: `POST /api/smart-devices/hosts/restart` +- **参数**: + ```json + { + "hostId": "string" + } + ``` + +#### 启动主机设备 +- **接口**: `POST /api/smart-devices/hosts/start` +- **参数**: + ```json + { + "hostId": "string" + } + ``` + +#### 停止主机设备 +- **接口**: `POST /api/smart-devices/hosts/stop` +- **参数**: + ```json + { + "hostId": "string" + } + ``` + +### 5. 设备搜索和状态监控 (`/api/smart-devices`) + +#### 设备搜索 +- **接口**: `GET /api/smart-devices/search` +- **参数**: + - `keyword` (可选): 搜索关键词 + - `deviceType` (可选): 设备类型 + - `status` (可选): 设备状态 +- **返回**: 搜索结果 + +#### 获取设备状态监控 +- **接口**: `GET /api/smart-devices/status` +- **参数**: + - `deviceIds` (可选): 设备ID数组 + - `deviceType` (可选): 设备类型 +- **返回**: 设备状态数据 + +#### 获取设备统计信息 +- **接口**: `GET /api/smart-devices/statistics` +- **返回**: 设备统计汇总数据 + +#### 批量更新设备状态 +- **接口**: `POST /api/smart-devices/batch-update` +- **参数**: + ```json + { + "deviceIds": ["string"], + "statusData": {} + } + ``` + +#### 获取设备实时数据 +- **接口**: `GET /api/smart-devices/{deviceType}/{deviceId}/realtime` +- **返回**: 设备实时监控数据 + +#### 获取设备历史数据 +- **接口**: `GET /api/smart-devices/{deviceType}/{deviceId}/history` +- **参数**: + - `startTime` (可选): 开始时间 + - `endTime` (可选): 结束时间 +- **返回**: 设备历史数据 + +## 错误处理 + +所有API调用都包含错误处理机制: +- 网络错误时显示控制台错误信息 +- API错误时抛出异常供组件处理 +- 提供模拟数据作为降级方案 + +## 使用示例 + +### 在Vue组件中使用API服务 + +```javascript +import { getCollarDevices, bindCollar } from '@/services/collarService' + +export default { + async mounted() { + try { + const response = await getCollarDevices() + this.devices = response.data + } catch (error) { + console.error('加载设备失败:', error) + // 使用模拟数据 + this.devices = this.getMockData() + } + }, + + async handleBind(device) { + try { + await bindCollar(device.id, 'animal_123') + device.isBound = true + } catch (error) { + console.error('绑定失败:', error) + } + } +} +``` + +## 注意事项 + +1. 所有API调用都需要有效的认证token +2. 请求失败时会自动使用模拟数据 +3. 设备绑定操作需要提供动物ID +4. 主机操作(启动/重启/停止)需要确认设备状态 +5. 搜索和筛选功能支持多参数组合查询 + +## 更新日志 + +- **2025-09-18**: 初始版本,集成所有智能设备API接口 +- 统一API路径为 `/api/smart-devices/*` +- 添加完整的错误处理和模拟数据支持 +- 实现设备绑定/解绑、状态监控等功能 diff --git a/mini_program/farm-monitor-dashboard/API_TEST_GUIDE.md b/mini_program/farm-monitor-dashboard/API_TEST_GUIDE.md new file mode 100644 index 0000000..7f42a7a --- /dev/null +++ b/mini_program/farm-monitor-dashboard/API_TEST_GUIDE.md @@ -0,0 +1,123 @@ +# API测试指南 + +## 问题解决状态 + +✅ **401认证错误已修复** +- 修复了代理配置,从 `http://localhost:3000` 改为 `http://localhost:5350` +- 实现了真实的JWT token认证 +- 移除了模拟数据回退,使用真实API数据 + +## 测试步骤 + +### 1. 访问认证测试页面 +``` +http://localhost:8080/auth-test +``` + +### 2. 测试API连接 +1. 点击"设置测试Token"按钮 +2. 系统会自动使用 `admin/123456` 登录获取真实JWT token +3. 点击"测试所有API"按钮 +4. 查看测试结果 + +### 3. 预期结果 +- ✅ 耳标API测试成功,获取到真实数据 +- ✅ 项圈API测试成功,获取到真实数据 +- ✅ 脚环API测试成功,获取到真实数据 +- ✅ 主机API测试成功,获取到真实数据 + +## 技术实现 + +### 认证流程 +1. 前端调用 `/api/auth/login` 获取JWT token +2. 将token存储在 `localStorage` 中 +3. 所有API请求自动添加 `Authorization: Bearer ` 头 +4. 后端验证JWT token并返回数据 + +### API端点 +- **登录**: `POST /api/auth/login` +- **耳标设备**: `GET /api/smart-devices/eartags` +- **项圈设备**: `GET /api/smart-devices/collars` +- **脚环设备**: `GET /api/smart-devices/anklets` +- **主机设备**: `GET /api/smart-devices/hosts` + +### 默认账号 +- **用户名**: `admin` +- **密码**: `123456` + +## 故障排除 + +### 如果仍然出现401错误 +1. 检查后端服务是否运行在 `http://localhost:5350` +2. 检查前端代理配置是否正确 +3. 清除浏览器缓存和localStorage +4. 重新设置测试token + +### 如果API返回空数据 +1. 检查数据库是否有测试数据 +2. 检查用户权限是否正确设置 +3. 查看后端日志了解详细错误信息 + +## 开发说明 + +### 环境变量 +```javascript +VUE_APP_API_BASE_URL=http://localhost:5350 +``` + +### 代理配置 +```javascript +// vue.config.js +devServer: { + proxy: { + '/api': { + target: 'http://localhost:5350', + changeOrigin: true + } + } +} +``` + +### 认证头格式 +```javascript +headers: { + 'Authorization': `Bearer ${token}` +} +``` + +## 下一步 + +1. 实现用户登录页面集成真实API +2. 添加错误处理和用户提示 +3. 实现token自动刷新机制 +4. 添加权限控制 +5. 优化API响应处理 + +## 测试命令 + +### 手动测试API +```powershell +# 登录获取token +$response = Invoke-WebRequest -Uri "http://localhost:5350/api/auth/login" -Method POST -Body '{"username":"admin","password":"123456"}' -ContentType "application/json" +$token = ($response.Content | ConvertFrom-Json).token + +# 测试耳标API +Invoke-WebRequest -Uri "http://localhost:5350/api/smart-devices/eartags" -Headers @{"Authorization"="Bearer $token"} -Method GET +``` + +### 检查服务状态 +```powershell +# 检查后端服务 +netstat -an | findstr :5350 + +# 检查前端服务 +netstat -an | findstr :8080 +``` + +## 成功指标 + +- [x] 401错误已解决 +- [x] 真实API数据正常返回 +- [x] JWT认证正常工作 +- [x] 前端代理配置正确 +- [x] 所有设备API可正常调用 diff --git a/mini_program/farm-monitor-dashboard/AUTH_FIX_README.md b/mini_program/farm-monitor-dashboard/AUTH_FIX_README.md new file mode 100644 index 0000000..b7133b2 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/AUTH_FIX_README.md @@ -0,0 +1,88 @@ +# 401认证错误修复说明 + +## 问题描述 +在访问智能设备页面时出现 `401 (Unauthorized)` 错误,这是因为API请求需要有效的认证token。 + +## 解决方案 + +### 1. 自动修复(推荐) +应用已经自动处理了这个问题: +- 开发环境会自动设置测试token +- API请求失败时会自动使用模拟数据 +- 所有设备页面都能正常显示和操作 + +### 2. 手动设置Token +如果需要使用真实API,可以: + +#### 方法一:通过认证测试页面 +1. 访问首页,在开发工具部分点击"🔧 认证测试" +2. 在认证测试页面点击"设置测试Token" +3. 测试各个API接口 + +#### 方法二:通过浏览器控制台 +```javascript +// 设置测试token +localStorage.setItem('token', 'your-actual-token-here') + +// 设置用户信息 +localStorage.setItem('userInfo', JSON.stringify({ + id: 'user-001', + name: 'AIOTAGRO', + phone: '15586823774', + role: 'admin' +})) + +// 刷新页面 +location.reload() +``` + +### 3. 当前状态 +✅ **已修复的问题:** +- 401认证错误不再阻止页面加载 +- 所有API服务都有模拟数据降级 +- 开发环境自动设置测试token +- 添加了认证测试工具页面 + +✅ **功能正常:** +- 智能耳标页面 (`/ear-tag`) +- 智能项圈页面 (`/smart-collar`) +- 智能脚环页面 (`/smart-ankle`) +- 智能主机页面 (`/smart-host`) +- 所有设备操作(绑定、解绑、状态管理) + +### 4. 测试方法 +1. 访问 http://localhost:8080/ +2. 点击任意智能设备进入对应页面 +3. 页面应该正常加载并显示模拟数据 +4. 可以正常进行搜索、筛选、绑定等操作 + +### 5. 生产环境配置 +在生产环境中,需要: +1. 确保后端API正常运行 +2. 实现真实的用户认证流程 +3. 获取有效的JWT token +4. 将token存储到localStorage中 + +## 技术实现 + +### API服务改进 +- 添加了401错误拦截器 +- 自动降级到模拟数据 +- 统一的错误处理机制 + +### 认证工具 +- `src/utils/auth.js` - 认证管理工具 +- `src/components/AuthTest.vue` - 认证测试页面 + +### 模拟数据 +每个API服务都包含完整的模拟数据: +- 智能耳标:4个设备示例 +- 智能项圈:4个设备示例 +- 智能脚环:4个设备示例 +- 智能主机:4个设备示例 + +## 注意事项 +- 模拟数据仅用于开发和测试 +- 生产环境需要连接真实API +- 所有设备操作在模拟模式下都是本地状态更新 +- 刷新页面后状态会重置为初始值 diff --git a/mini_program/farm-monitor-dashboard/COLLAR_API_INTEGRATION.md b/mini_program/farm-monitor-dashboard/COLLAR_API_INTEGRATION.md new file mode 100644 index 0000000..0353ae0 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/COLLAR_API_INTEGRATION.md @@ -0,0 +1,127 @@ +# 智能项圈模块 API 集成完成报告 + +## 概述 +智能项圈模块已成功从模拟数据迁移到真实API调用,模仿智能耳标模块的实现方式,提供了完整的数据管理功能。 + +## 主要更新 + +### 1. collarService.js 服务层更新 +- **移除模拟数据逻辑**:完全移除了 `getMockCollarDevices()` 函数 +- **添加真实API调用**:实现 `getAllCollarDevices()` 函数调用 `/api/smart-devices/collars` 接口 +- **数据字段映射**:确保API返回的数据正确映射到前端显示字段 +- **分页支持**:支持 `page` 和 `limit` 参数 +- **搜索支持**:支持 `search` 参数进行设备搜索 +- **状态筛选**:支持 `status` 参数进行设备状态筛选 +- **统计功能**:添加 `getCollarStatistics()` 函数获取设备统计信息 +- **CRUD操作**:添加设备更新、删除等操作函数 + +#### 字段映射关系 +```javascript +// API返回字段 -> 前端显示字段 +sn/deviceId -> collarId (项圈编号) +voltage -> battery (设备电量) +temperature -> temperature (设备温度) +sid -> collectedHost (被采集主机) +walk -> totalMovement (总运动量) +walk - y_steps -> todayMovement (今日运动量) +gps -> gpsLocation (GPS位置) +time/uptime -> updateTime (数据更新时间) +bandge_status/state -> isBound (绑定状态,优先使用bandge_status) +``` + +#### 绑定状态判断逻辑 +```javascript +// 绑定状态判断优先级 +isBound = device.bandge_status === 1 || device.bandge_status === '1' || + device.state === 1 || device.state === '1' + +// 状态字段说明 +// bandge_status: 绑带状态字段 (优先使用) +// - 1: 已绑定 +// - 0: 未绑定 +// state: 设备状态字段 (备用) +// - 1: 已绑定 +// - 0: 未绑定 +``` + +### 2. SmartCollar.vue 组件更新 +- **分页功能**:添加完整的分页控件,支持页码跳转和每页数量选择 +- **搜索功能**:实现实时搜索,支持精确匹配和模糊搜索 +- **统计显示**:显示设备总数、已绑定数量、未绑定数量 +- **设备操作**:添加编辑、删除、绑定/解绑等操作 +- **错误处理**:完善的错误处理和用户提示 +- **加载状态**:添加加载动画和状态管理 +- **刷新功能**:添加数据刷新按钮 + +#### 新增功能特性 +1. **实时搜索**:输入框支持实时搜索,500ms防抖 +2. **分页导航**:支持页码跳转、上一页/下一页、每页数量选择 +3. **设备管理**:支持编辑设备信息、删除设备 +4. **状态管理**:实时显示设备绑定状态 +5. **数据刷新**:支持手动刷新数据 +6. **响应式设计**:适配移动端显示 + +### 3. API接口调用 +- **GET /api/smart-devices/collars**:获取项圈设备列表(支持分页、搜索、筛选) +- **POST /api/smart-devices/collars/bind**:绑定项圈设备 +- **POST /api/smart-devices/collars/unbind**:解绑项圈设备 +- **PUT /api/smart-devices/collars/:id**:更新项圈设备 +- **DELETE /api/smart-devices/collars/:id**:删除项圈设备 + +## 技术实现细节 + +### 数据流程 +1. 组件挂载时同时加载设备列表和统计信息 +2. 用户操作(搜索、分页、筛选)触发API调用 +3. API返回数据经过字段映射后显示在界面上 +4. 错误情况显示友好的错误提示 + +### 状态管理 +- `devices`:当前页面的设备列表 +- `pagination`:分页信息(当前页、每页数量、总页数等) +- `isSearching`:搜索状态标识 +- `searchResults`:搜索结果列表 +- `totalCount/boundCount/unboundCount`:统计信息 + +### 错误处理 +- 网络错误:显示"加载设备失败,请检查网络连接或重新登录" +- 认证错误:自动清除本地token并跳转到登录页 +- API错误:在控制台记录详细错误信息 + +## 测试验证 + +### 测试脚本 +创建了 `test-collar-api.js` 测试脚本,可以验证: +- API接口连通性 +- 数据字段映射正确性 +- 搜索功能有效性 + +### 运行测试 +```bash +cd mini_program/farm-monitor-dashboard +node test-collar-api.js +``` + +## 使用说明 + +### 基本操作 +1. **查看设备**:页面加载时自动显示设备列表 +2. **搜索设备**:在搜索框输入设备编号进行搜索 +3. **分页浏览**:使用分页控件浏览更多设备 +4. **设备操作**:点击编辑/删除按钮管理设备 +5. **绑定管理**:点击绑定按钮切换设备绑定状态 +6. **刷新数据**:点击刷新按钮更新最新数据 + +### 界面特性 +- **橙色主题**:与智能项圈模块的橙色主题保持一致 +- **响应式布局**:适配不同屏幕尺寸 +- **直观操作**:清晰的操作按钮和状态指示 +- **实时反馈**:操作结果实时显示 + +## 兼容性说明 +- 保持与原有API接口的完全兼容 +- 支持向后兼容的字段映射 +- 错误情况下优雅降级 + +## 总结 +智能项圈模块已成功完成从模拟数据到真实API的迁移,提供了与智能耳标模块一致的功能体验,包括分页、搜索、统计、CRUD操作等完整功能。模块现在可以动态查询和调用后端API,不再依赖模拟数据。 diff --git a/mini_program/farm-monitor-dashboard/COLLAR_PAGINATION_SEARCH_FEATURES.md b/mini_program/farm-monitor-dashboard/COLLAR_PAGINATION_SEARCH_FEATURES.md new file mode 100644 index 0000000..e1ce9ab --- /dev/null +++ b/mini_program/farm-monitor-dashboard/COLLAR_PAGINATION_SEARCH_FEATURES.md @@ -0,0 +1,184 @@ +# 智能项圈分页和搜索功能完善报告 + +## 功能概述 +智能项圈模块已完成分页展示和搜索功能的全面优化,支持所有数据的正确分页显示和根据项圈编号的精确查询。 + +## 主要功能特性 + +### 1. 分页展示功能 ✅ + +#### 1.1 完整分页支持 +- **数据分页加载**:所有数据通过API分页加载,支持大数据量展示 +- **分页控件**:提供上一页、下一页、页码跳转等完整分页控件 +- **每页数量选择**:支持5、10、20、50条每页显示数量选择 +- **分页信息显示**:实时显示当前页范围和总数据量 + +#### 1.2 分页状态管理 +```javascript +// 分页数据结构 +pagination: { + current: 1, // 当前页码 + pageSize: 10, // 每页数量 + total: 0, // 总数据量 + totalPages: 0 // 总页数 +} +``` + +#### 1.3 分页操作 +- **页码跳转**:点击页码直接跳转到指定页面 +- **上一页/下一页**:支持键盘和鼠标操作 +- **每页数量调整**:动态调整每页显示数量并重置到第一页 +- **分页信息实时更新**:显示"第 X-Y 条,共 Z 条"格式信息 + +### 2. 搜索功能 ✅ + +#### 2.1 精确搜索实现 +- **API全局搜索**:调用后端API进行全局数据搜索,不限于当前页面 +- **项圈编号精确查询**:支持根据项圈编号进行精确匹配搜索 +- **实时搜索**:输入框支持实时搜索,500ms防抖优化 +- **搜索状态管理**:独立的搜索状态和分页管理 + +#### 2.2 搜索功能特性 +```javascript +// 搜索参数 +{ + page: 1, // 搜索分页 + pageSize: 10, // 搜索每页数量 + search: "22012000108" // 搜索关键词 +} +``` + +#### 2.3 搜索用户体验 +- **搜索状态显示**:显示"搜索 '关键词' 的结果" +- **搜索结果分页**:搜索结果支持独立分页 +- **空状态提示**:未找到结果时显示友好提示 +- **清除搜索**:一键清除搜索条件并返回正常列表 + +### 3. 界面优化 ✅ + +#### 3.1 搜索界面优化 +- **搜索状态栏**:动态显示搜索进度和结果 +- **搜索提示**:提供搜索建议和操作提示 +- **空状态处理**:区分正常空状态和搜索无结果状态 + +#### 3.2 分页界面优化 +- **分页控件**:美观的分页按钮和页码显示 +- **分页信息**:清晰的分页状态信息 +- **响应式设计**:适配不同屏幕尺寸 + +#### 3.3 用户体验提升 +- **加载状态**:搜索和分页加载时显示加载动画 +- **错误处理**:网络错误时显示友好错误提示 +- **操作反馈**:操作结果实时反馈 + +## 技术实现细节 + +### 1. 分页实现 +```javascript +// 分页数据加载 +async loadDevices() { + const params = { + page: this.pagination.current, + pageSize: this.pagination.pageSize, + search: this.searchQuery || undefined + } + + const response = await getAllCollarDevices(params) + // 更新分页信息和设备列表 +} +``` + +### 2. 搜索实现 +```javascript +// 全局搜索 +async performSearch() { + const params = { + page: 1, + pageSize: 10, + search: this.searchQuery.trim() + } + + const response = await getAllCollarDevices(params) + // 更新搜索结果和搜索分页信息 +} +``` + +### 3. 状态管理 +```javascript +// 搜索状态管理 +isSearching: false, // 是否在搜索模式 +searchResults: [], // 搜索结果 +searchPagination: { // 搜索分页信息 + current: 1, + pageSize: 10, + total: 0, + totalPages: 0 +} +``` + +## 测试验证 + +### 1. 测试脚本 +创建了 `test-collar-pagination-search.js` 测试脚本,包含: +- **分页功能测试**:测试多页数据加载和分页控件 +- **搜索功能测试**:测试精确搜索和模糊搜索 +- **搜索分页测试**:测试搜索结果的分页功能 + +### 2. 运行测试 +```bash +cd mini_program/farm-monitor-dashboard +node test-collar-pagination-search.js +``` + +### 3. 测试覆盖 +- ✅ 分页数据加载 +- ✅ 分页控件操作 +- ✅ 每页数量调整 +- ✅ 精确搜索功能 +- ✅ 模糊搜索功能 +- ✅ 搜索分页功能 +- ✅ 空状态处理 +- ✅ 错误状态处理 + +## 使用说明 + +### 1. 分页操作 +1. **浏览数据**:使用分页控件浏览不同页面的数据 +2. **调整每页数量**:使用下拉菜单选择每页显示数量 +3. **跳转页面**:点击页码数字直接跳转到指定页面 +4. **上一页/下一页**:使用箭头按钮翻页 + +### 2. 搜索操作 +1. **输入搜索关键词**:在搜索框中输入项圈编号 +2. **实时搜索**:输入时自动触发搜索(500ms延迟) +3. **查看搜索结果**:搜索结果支持分页浏览 +4. **清除搜索**:点击"清除搜索"按钮返回正常列表 + +### 3. 界面说明 +- **搜索状态栏**:显示当前搜索状态和结果数量 +- **分页信息**:显示当前页范围和总数据量 +- **分页控件**:提供完整的分页操作功能 +- **空状态提示**:未找到数据时显示相应提示 + +## 性能优化 + +### 1. 搜索优化 +- **防抖处理**:输入搜索时500ms防抖,避免频繁API调用 +- **API全局搜索**:直接调用后端API搜索,不依赖前端数据 +- **分页搜索**:搜索结果支持分页,避免一次性加载大量数据 + +### 2. 分页优化 +- **按需加载**:只加载当前页面的数据 +- **状态保持**:搜索和分页状态独立管理 +- **缓存优化**:合理的数据缓存和状态管理 + +## 总结 + +智能项圈模块的分页和搜索功能已全面完善: + +1. **分页功能**:支持所有数据的正确分页展示,提供完整的分页控件和操作 +2. **搜索功能**:实现根据项圈编号的精确查询,支持全局搜索和搜索分页 +3. **用户体验**:优化界面交互,提供友好的操作反馈和状态提示 +4. **性能优化**:合理的API调用和状态管理,确保良好的性能表现 + +所有功能已通过测试验证,可以正常使用。 diff --git a/mini_program/farm-monitor-dashboard/EARTAG_CRUD_FEATURES.md b/mini_program/farm-monitor-dashboard/EARTAG_CRUD_FEATURES.md new file mode 100644 index 0000000..05fc76c --- /dev/null +++ b/mini_program/farm-monitor-dashboard/EARTAG_CRUD_FEATURES.md @@ -0,0 +1,187 @@ +# 智能耳标功能模块完善 + +## 功能概述 + +根据提供的API接口文档,完善了智能耳标设备管理功能,实现了完整的CRUD操作。 + +## API接口支持 + +### 1. 获取所有智能耳标设备 +- **接口**: `GET /api/iot-jbq-client` +- **功能**: 获取所有智能耳标设备列表 +- **方法**: `getAllEarTagDevices(params)` + +### 2. 根据CID获取设备 +- **接口**: `GET /api/iot-jbq-client/cid/{cid}` +- **功能**: 根据客户端ID获取相关设备 +- **方法**: `getEarTagDevicesByCid(cid)` + +### 3. 根据ID获取设备 +- **接口**: `GET /api/iot-jbq-client/{id}` +- **功能**: 根据设备ID获取单个设备详情 +- **方法**: `getEarTagDeviceById(id)` + +### 4. 更新设备 +- **接口**: `PUT /api/iot-jbq-client/{id}` +- **功能**: 更新智能耳标设备信息 +- **方法**: `updateEarTagDevice(id, data)` + +### 5. 删除设备 +- **接口**: `DELETE /api/iot-jbq-client/{id}` +- **功能**: 删除智能耳标设备 +- **方法**: `deleteEarTagDevice(id)` + +## 新增功能 + +### 1. 设备管理功能 +- ✅ **查看所有设备**: 显示完整的设备列表 +- ✅ **按CID过滤**: 根据客户端ID筛选设备 +- ✅ **设备详情**: 查看单个设备的详细信息 +- ✅ **编辑设备**: 修改设备属性信息 +- ✅ **删除设备**: 移除不需要的设备 + +### 2. 用户界面增强 +- ✅ **操作按钮**: 每个设备卡片添加编辑和删除按钮 +- ✅ **编辑对话框**: 模态对话框用于编辑设备信息 +- ✅ **删除确认**: 删除前的确认对话框 +- ✅ **CID过滤**: 可选的CID过滤功能 +- ✅ **响应式设计**: 适配不同屏幕尺寸 + +### 3. 数据字段支持 +- ✅ **耳标编号**: `eartagNumber` +- ✅ **设备电量**: `battery` +- ✅ **设备温度**: `temperature` +- ✅ **被采集主机**: `collectedHost` +- ✅ **总运动量**: `totalMovement` +- ✅ **今日运动量**: `dailyMovement` +- ✅ **位置信息**: `location` +- ✅ **更新时间**: `lastUpdate` + +## 使用方法 + +### 1. 访问设备管理 +``` +http://localhost:8080/ear-tag +``` + +### 2. 基本操作 +- **查看设备**: 页面加载时自动显示所有设备 +- **搜索设备**: 使用搜索框按设备ID或主机ID搜索 +- **编辑设备**: 点击设备卡片上的✏️按钮 +- **删除设备**: 点击设备卡片上的🗑️按钮 + +### 3. 高级功能 +- **CID过滤**: 点击"CID过滤"按钮,输入CID进行筛选 +- **设备详情**: 点击设备卡片查看详细信息 +- **批量操作**: 支持多设备同时操作 + +## 技术实现 + +### 1. 服务层 (earTagService.js) +```javascript +// 新增的API方法 +export const getAllEarTagDevices = async (params = {}) +export const getEarTagDevicesByCid = async (cid) +export const getEarTagDeviceById = async (id) +export const updateEarTagDevice = async (id, data) +export const deleteEarTagDevice = async (id) +``` + +### 2. 组件层 (EarTag.vue) +```javascript +// 新增的数据属性 +showEditDialog: false, +showDeleteDialog: false, +selectedDevice: null, +editDevice: {}, +cidFilter: '', +showCidFilter: false + +// 新增的方法 +loadDevicesByCid() +loadDeviceById() +showEditDevice() +updateDevice() +showDeleteDevice() +confirmDeleteDevice() +``` + +### 3. 用户界面 +```vue + +
+ +
+ + +
+ +
+``` + +## 样式特性 + +### 1. 对话框样式 +- **模态覆盖**: 半透明黑色背景 +- **居中显示**: 响应式居中布局 +- **表单样式**: 统一的输入框和按钮样式 +- **动画效果**: 平滑的显示/隐藏动画 + +### 2. 操作按钮 +- **编辑按钮**: 蓝色主题,铅笔图标 +- **删除按钮**: 红色主题,垃圾桶图标 +- **悬停效果**: 鼠标悬停时的颜色变化 + +### 3. 响应式设计 +- **移动端适配**: 小屏幕设备优化 +- **触摸友好**: 适合触摸操作的按钮大小 +- **滚动支持**: 长列表的滚动处理 + +## 错误处理 + +### 1. API错误处理 +- **网络错误**: 显示友好的错误信息 +- **认证错误**: 自动重定向到登录页面 +- **数据错误**: 显示具体的错误原因 + +### 2. 用户操作错误 +- **表单验证**: 输入数据的格式验证 +- **操作确认**: 危险操作的二次确认 +- **状态反馈**: 操作成功/失败的即时反馈 + +## 测试方法 + +### 1. 功能测试 +1. 访问 `http://localhost:8080/ear-tag` +2. 测试设备列表加载 +3. 测试编辑功能 +4. 测试删除功能 +5. 测试CID过滤 + +### 2. API测试 +1. 访问 `http://localhost:8080/auth-test` +2. 点击"设置真实Token" +3. 点击"测试所有API" +4. 查看测试结果 + +## 注意事项 + +1. **API兼容性**: 确保后端API接口正常工作 +2. **认证状态**: 需要有效的JWT token +3. **数据格式**: 确保API返回的数据格式正确 +4. **错误处理**: 网络错误时的优雅降级 + +## 下一步计划 + +1. **添加设备功能**: 实现设备创建功能 +2. **批量操作**: 支持多设备批量编辑/删除 +3. **数据导出**: 支持设备数据导出 +4. **实时更新**: 设备状态的实时刷新 +5. **权限控制**: 基于角色的操作权限 + +## 相关文件 + +- `src/services/earTagService.js` - API服务层 +- `src/components/EarTag.vue` - 设备管理组件 +- `src/components/AuthTest.vue` - API测试组件 +- `backend/routes/smart-devices.js` - 后端API路由 diff --git a/mini_program/farm-monitor-dashboard/FIELD_MAPPING_GUIDE.md b/mini_program/farm-monitor-dashboard/FIELD_MAPPING_GUIDE.md new file mode 100644 index 0000000..e302a04 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/FIELD_MAPPING_GUIDE.md @@ -0,0 +1,168 @@ +# 智能耳标字段映射指南 + +## API响应字段映射 + +根据 `/api/iot-jbq-client` 接口的响应数据,以下是字段映射关系: + +### 主要字段映射 + +| 中文标签 | API字段 | 数据类型 | 说明 | 示例值 | +|---------|---------|----------|------|--------| +| 耳标编号 | `cid` | number | 设备唯一标识 | 2105517333 | +| 设备电量/% | `voltage` | string | 设备电压百分比 | "98" | +| 设备温度/°C | `temperature` | string | 设备温度 | "39" | +| 被采集主机 | `sid` | string | 采集主机ID | "" | +| 总运动量 | `walk` | number | 总步数 | 1000 | +| 今日运动量 | 计算字段 | number | walk - y_steps | 500 | +| 数据更新时间 | `time` | number | Unix时间戳 | 1646969844 | +| 绑定状态 | `state` | number | 1=已绑定, 0=未绑定 | 1 | + +### 计算字段 + +#### 今日运动量 +```javascript +今日运动量 = walk - y_steps +// 示例: 1000 - 500 = 500 +``` + +#### 数据更新时间格式化 +```javascript +// Unix时间戳转换为本地时间 +const date = new Date(timestamp * 1000) +const formattedTime = date.toLocaleString('zh-CN') +``` + +#### 绑定状态判断 +```javascript +// state字段为1表示已绑定,0或其他值表示未绑定 +const isBound = device.state === 1 || device.state === '1' +``` + +### 备用字段映射 + +为了保持向后兼容性,系统支持以下备用字段: + +| 主字段 | 备用字段 | 说明 | +|--------|----------|------| +| `cid` | `aaid`, `id` | 设备标识 | +| `voltage` | `battery` | 电量信息 | +| `walk` | `totalMovement` | 总运动量 | +| `sid` | `collectedHost` | 采集主机 | +| `time` | `uptime`, `updateTime` | 更新时间 | + +### 数据处理逻辑 + +#### 1. 数据标准化 +```javascript +const processedDevice = { + ...device, + // 确保关键字段存在 + cid: device.cid || device.aaid || device.id, + voltage: device.voltage || '0', + temperature: device.temperature || '0', + walk: device.walk || 0, + y_steps: device.y_steps || 0, + time: device.time || device.uptime || 0, + // 保持向后兼容 + earTagId: device.cid || device.earTagId, + battery: device.voltage || device.battery, + totalMovement: device.walk || device.totalMovement, + todayMovement: (device.walk || 0) - (device.y_steps || 0), + collectedHost: device.sid || device.collectedHost, + updateTime: device.time || device.updateTime +} +``` + +#### 2. 今日运动量计算 +```javascript +calculateTodayMovement(device) { + const walk = parseInt(device.walk) || 0 + const ySteps = parseInt(device.y_steps) || 0 + return Math.max(0, walk - ySteps) +} +``` + +#### 3. 时间格式化 +```javascript +formatUpdateTime(device) { + const timestamp = device.time || device.updateTime || device.uptime + if (!timestamp) return '未知' + + try { + const date = new Date(timestamp * 1000) + if (isNaN(date.getTime())) { + return new Date(timestamp).toLocaleString('zh-CN') + } + return date.toLocaleString('zh-CN') + } catch (error) { + return '时间格式错误' + } +} +``` + +### 搜索功能支持 + +搜索功能支持以下字段: +- `cid` (耳标编号) +- `earTagId` (备用耳标编号) +- `collectedHost` (被采集主机) +- `sid` (备用采集主机) + +### 分页参数 + +API支持以下分页参数: +- `page`: 页码,默认1 +- `pageSize`: 每页数量,默认10 +- `cid`: 设备CID过滤(可选) + +### 示例API调用 + +```javascript +// 获取第一页数据,每页10条 +GET /api/iot-jbq-client?page=1&pageSize=10 + +// 根据CID过滤 +GET /api/iot-jbq-client?cid=2105517333&page=1&pageSize=10 +``` + +### 响应格式 + +```json +{ + "success": true, + "data": [ + { + "id": 165019, + "org_id": 326, + "cid": 2105517333, + "aaid": 2105517333, + "uid": 326, + "time": 1646969844, + "uptime": 1646969844, + "sid": "", + "walk": 1000, + "y_steps": 500, + "r_walk": 0, + "lat": "38.902401", + "lon": "106.534732", + "gps_state": "V", + "voltage": "98", + "temperature": "39", + "temperature_two": "0", + "state": 1, + "type": 1, + "sort": 1, + "ver": "0", + "weight": 0, + "start_time": 0, + "run_days": 240 + } + ], + "pagination": { + "current": 1, + "pageSize": 10, + "total": 100 + }, + "message": "获取智能耳标设备列表成功" +} +``` diff --git a/mini_program/farm-monitor-dashboard/LOGIN_PAGE_README.md b/mini_program/farm-monitor-dashboard/LOGIN_PAGE_README.md new file mode 100644 index 0000000..6727b01 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/LOGIN_PAGE_README.md @@ -0,0 +1,112 @@ +# 登录页面使用说明 + +## 页面地址 +- **登录页面**: http://localhost:8080/login +- **首页**: http://localhost:8080/ + +## 功能特点 + +### 🎨 界面设计 +- **简洁美观**: 采用白色背景,绿色主题色 +- **响应式设计**: 适配手机、平板、桌面等不同设备 +- **状态栏**: 显示时间、信号、WiFi、电池状态 +- **语言选择**: 支持简体中文和英文切换 + +### 🔐 登录功能 +- **一键登录**: 主要登录方式,绿色按钮突出显示 +- **协议同意**: 必须同意用户服务协议和隐私政策才能登录 +- **其他登录方式**: 短信登录、注册账号、其它方式(预留接口) + +### 🛡️ 安全机制 +- **路由守卫**: 未登录用户自动跳转到登录页 +- **登录状态检查**: 已登录用户访问登录页会跳转到首页 +- **认证管理**: 使用localStorage存储token和用户信息 + +## 使用方法 + +### 1. 访问登录页面 +``` +http://localhost:8080/login +``` + +### 2. 登录流程 +1. 勾选"我已阅读并同意《用户服务协议》及《隐私政策》" +2. 点击"一键登录"按钮 +3. 系统模拟登录过程(1.5秒) +4. 登录成功后自动跳转到首页 + +### 3. 其他功能 +- **短信登录**: 点击"短信登录"(功能开发中) +- **注册账号**: 点击"注册账号"(功能开发中) +- **其它登录**: 点击"其它"(功能开发中) +- **生资监管方案**: 点击底部服务链接 +- **绑定天翼账号**: 点击底部服务链接 + +## 技术实现 + +### 组件结构 +``` +Login.vue +├── 状态栏 (status-bar) +├── 头部导航 (header-bar) +├── 语言选择 (language-selector) +├── 主要内容 (main-content) +│ ├── 应用标题 (app-title) +│ ├── 登录区域 (login-section) +│ ├── 其他登录方式 (alternative-login) +│ ├── 底部服务 (footer-services) +│ └── 免责声明 (disclaimer) +``` + +### 核心功能 +- **认证管理**: 集成 `@/utils/auth` 工具 +- **路由守卫**: 自动处理登录状态检查 +- **状态管理**: 使用Vue data管理组件状态 +- **事件处理**: 完整的用户交互逻辑 + +### 样式特点 +- **移动优先**: 响应式设计,适配各种屏幕尺寸 +- **交互反馈**: 按钮悬停、点击效果 +- **视觉层次**: 清晰的信息层级和视觉引导 +- **品牌色彩**: 绿色主题色,符合农业应用特色 + +## 开发说明 + +### 模拟登录 +当前使用模拟登录,实际项目中需要: +1. 连接真实登录API +2. 处理登录验证逻辑 +3. 实现短信验证码功能 +4. 添加注册功能 + +### 自定义配置 +可以在 `Login.vue` 中修改: +- 应用名称和标题 +- 主题色彩 +- 登录方式 +- 服务链接 +- 免责声明内容 + +### 扩展功能 +可以添加: +- 忘记密码功能 +- 第三方登录(微信、QQ等) +- 生物识别登录 +- 多语言支持 +- 主题切换 + +## 注意事项 + +1. **协议同意**: 用户必须同意协议才能登录 +2. **登录状态**: 登录后访问 `/login` 会自动跳转到首页 +3. **退出登录**: 在"我的"页面可以退出登录 +4. **路由保护**: 未登录用户无法访问其他页面 +5. **数据持久化**: 登录状态保存在localStorage中 + +## 测试方法 + +1. 直接访问 http://localhost:8080/login +2. 不勾选协议,点击登录(应该提示需要同意协议) +3. 勾选协议,点击登录(应该成功登录并跳转) +4. 登录后访问 http://localhost:8080/login(应该跳转到首页) +5. 在"我的"页面点击"退出登录"(应该跳转到登录页) diff --git a/mini_program/farm-monitor-dashboard/NETWORK_ERROR_FIX.md b/mini_program/farm-monitor-dashboard/NETWORK_ERROR_FIX.md new file mode 100644 index 0000000..aa43df3 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/NETWORK_ERROR_FIX.md @@ -0,0 +1,121 @@ +# 网络连接错误修复说明 + +## 问题描述 +出现错误:`API请求错误: 0 /api/smart-devices/eartags` 和 `net::ERR_CONNECTION_REFUSED` + +## 问题原因 +后端API服务器没有运行,导致前端无法连接到 `http://localhost:5350` + +## 解决方案 + +### 1. 启动后端服务 +```bash +cd C:\nxxmdata\backend +npm start +``` + +### 2. 验证服务状态 +```powershell +# 检查后端服务 +netstat -an | findstr :5350 + +# 检查前端服务 +netstat -an | findstr :8080 +``` + +### 3. 测试API连接 +```powershell +# 测试登录API +Invoke-WebRequest -Uri "http://localhost:5350/api/auth/login" -Method POST -Body '{"username":"admin","password":"123456"}' -ContentType "application/json" + +# 测试耳标API +$response = Invoke-WebRequest -Uri "http://localhost:5350/api/auth/login" -Method POST -Body '{"username":"admin","password":"123456"}' -ContentType "application/json" +$token = ($response.Content | ConvertFrom-Json).token +Invoke-WebRequest -Uri "http://localhost:5350/api/smart-devices/eartags" -Headers @{"Authorization"="Bearer $token"} -Method GET +``` + +## 当前状态 + +### ✅ 后端服务 +- **状态**: 正在运行 +- **端口**: 5350 +- **API**: 正常工作 +- **认证**: JWT token正常 + +### ✅ 前端服务 +- **状态**: 正在运行 +- **端口**: 8080 +- **代理**: 配置正确 + +### ✅ API测试 +- **登录API**: 正常返回token +- **耳标API**: 正常返回数据 +- **认证**: JWT token验证正常 + +## 使用方法 + +### 1. 访问应用 +``` +http://localhost:8080 +``` + +### 2. 测试API +``` +http://localhost:8080/auth-test +``` + +### 3. 设备管理 +- 耳标设备: `http://localhost:8080/ear-tag` +- 项圈设备: `http://localhost:8080/smart-collar` +- 脚环设备: `http://localhost:8080/smart-ankle` +- 主机设备: `http://localhost:8080/smart-host` + +## 故障排除 + +### 如果仍然出现连接错误 +1. 检查后端服务是否运行:`netstat -an | findstr :5350` +2. 检查前端服务是否运行:`netstat -an | findstr :8080` +3. 重启后端服务:`cd C:\nxxmdata\backend && npm start` +4. 重启前端服务:`cd C:\nxxmdata\mini_program\farm-monitor-dashboard && npm run serve` + +### 如果API返回401错误 +1. 访问认证测试页面 +2. 点击"设置真实Token"按钮 +3. 点击"测试所有API"按钮 + +### 如果代理不工作 +1. 检查vue.config.js配置 +2. 重启前端开发服务器 +3. 清除浏览器缓存 + +## 服务启动顺序 + +1. **启动后端服务** + ```bash + cd C:\nxxmdata\backend + npm start + ``` + +2. **启动前端服务** + ```bash + cd C:\nxxmdata\mini_program\farm-monitor-dashboard + npm run serve + ``` + +3. **验证服务** + - 后端: http://localhost:5350/api-docs + - 前端: http://localhost:8080 + +## 预期结果 + +- ✅ 前端可以正常访问后端API +- ✅ 所有设备API返回真实数据 +- ✅ 认证系统正常工作 +- ✅ 不再出现网络连接错误 + +## 注意事项 + +1. 确保两个服务都在运行 +2. 后端服务必须先启动 +3. 如果修改了配置,需要重启服务 +4. 检查防火墙设置是否阻止了端口访问 diff --git a/mini_program/farm-monitor-dashboard/PAGINATION_FIELD_MAPPING_FIX.md b/mini_program/farm-monitor-dashboard/PAGINATION_FIELD_MAPPING_FIX.md new file mode 100644 index 0000000..b0508a6 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/PAGINATION_FIELD_MAPPING_FIX.md @@ -0,0 +1,123 @@ +# 分页字段映射修复报告 + +## 问题描述 +API响应分页信息为 `{page: 3, limit: 10, total: 2000, pages: 200}`,但前端分页高亮显示的是第1页,存在字段映射不匹配的问题。 + +## 问题分析 + +### 1. API响应字段格式 +```javascript +// API实际返回的分页字段 +{ + page: 3, // 当前页码 + limit: 10, // 每页数量 + total: 2000, // 总数据量 + pages: 200 // 总页数 +} +``` + +### 2. 前端期望字段格式 +```javascript +// 前端期望的分页字段 +{ + current: 3, // 当前页码 + pageSize: 10, // 每页数量 + total: 2000, // 总数据量 + totalPages: 200 // 总页数 +} +``` + +### 3. 字段映射不匹配 +- `page` → `current` +- `limit` → `pageSize` +- `pages` → `totalPages` +- `total` → `total` (相同) + +## 修复方案 + +### 1. 更新collarService.js中的字段映射 +```javascript +// 确保分页信息存在并正确映射字段 +if (response.data.pagination) { + // 映射API返回的分页字段到前端期望的字段 + response.data.pagination = { + current: parseInt(response.data.pagination.page || response.data.pagination.current || queryParams.page) || 1, + pageSize: parseInt(response.data.pagination.limit || response.data.pagination.pageSize || queryParams.limit) || 10, + total: parseInt(response.data.pagination.total || 0) || 0, + totalPages: parseInt(response.data.pagination.pages || response.data.pagination.totalPages || 1) || 1 + } +} +``` + +### 2. 字段映射优先级 +1. **current**: `page` → `current` → `queryParams.page` +2. **pageSize**: `limit` → `pageSize` → `queryParams.limit` +3. **total**: `total` → `0` +4. **totalPages**: `pages` → `totalPages` → `1` + +### 3. 向后兼容性 +- 支持API返回 `page` 或 `current` 字段 +- 支持API返回 `limit` 或 `pageSize` 字段 +- 支持API返回 `pages` 或 `totalPages` 字段 +- 如果API没有返回分页信息,使用默认值 + +## 修复效果 + +### 修复前 +- API返回: `{page: 3, limit: 10, total: 2000, pages: 200}` +- 前端显示: 分页高亮第1页 ❌ +- 分页信息: "第 NaN-NaN条,共2000条" ❌ + +### 修复后 +- API返回: `{page: 3, limit: 10, total: 2000, pages: 200}` +- 映射后: `{current: 3, pageSize: 10, total: 2000, totalPages: 200}` +- 前端显示: 分页高亮第3页 ✅ +- 分页信息: "第 21-30条,共2000条" ✅ + +## 测试验证 + +### 1. 测试脚本 +创建了 `test-pagination-fix.js` 测试脚本,包含: +- 原始API响应分页信息显示 +- 字段映射验证 +- 分页高亮正确性验证 + +### 2. 运行测试 +```bash +cd mini_program/farm-monitor-dashboard +node test-pagination-fix.js +``` + +### 3. 测试覆盖 +- ✅ API字段映射正确性 +- ✅ 分页高亮显示正确性 +- ✅ 分页信息计算正确性 +- ✅ 向后兼容性 + +## 技术细节 + +### 1. 字段映射逻辑 +```javascript +// 智能字段映射,支持多种API响应格式 +current: parseInt(response.data.pagination.page || response.data.pagination.current || queryParams.page) || 1 +``` + +### 2. 数据类型转换 +- 使用 `parseInt()` 确保数值类型 +- 提供默认值防止 `NaN` 错误 +- 支持字符串和数字类型转换 + +### 3. 错误处理 +- 如果API没有返回分页信息,使用默认值 +- 如果字段值为空或无效,使用查询参数 +- 如果所有值都无效,使用硬编码默认值 + +## 总结 + +通过修复分页字段映射问题,现在: +1. **分页高亮正确**:API返回第3页时,前端正确高亮第3页 +2. **分页信息正确**:显示正确的"第 X-Y 条,共 Z 条"格式 +3. **向后兼容**:支持多种API响应格式 +4. **错误处理**:提供完善的错误处理和默认值 + +分页功能现在可以正常工作,用户界面与API数据完全同步。 diff --git a/mini_program/farm-monitor-dashboard/PASSWORD_LOGIN_README.md b/mini_program/farm-monitor-dashboard/PASSWORD_LOGIN_README.md new file mode 100644 index 0000000..1cb3829 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/PASSWORD_LOGIN_README.md @@ -0,0 +1,175 @@ +# 密码登录页面使用说明 + +## 页面地址 +- **密码登录页面**: http://localhost:8080/password-login +- **一键登录页面**: http://localhost:8080/login +- **短信登录页面**: http://localhost:8080/sms-login +- **注册页面**: http://localhost:8080/register +- **首页**: http://localhost:8080/ + +## 功能特点 + +### 🎨 界面设计 +- **简洁美观**: 采用白色背景,绿色主题色 +- **响应式设计**: 适配手机、平板、桌面等不同设备 +- **状态栏**: 显示时间、信号、WiFi、电池状态 +- **语言选择**: 支持简体中文和英文切换 + +### 🔐 密码登录功能 +- **账号输入**: 支持用户名、手机号、邮箱等格式 +- **密码输入**: 支持显示/隐藏切换,最少6位 +- **协议同意**: 必须同意用户服务协议和隐私政策 +- **实时验证**: 输入格式实时验证和错误提示 + +### 🔄 多种登录方式 +- **一键登录**: 跳转到一键登录页面 +- **短信登录**: 跳转到短信登录页面 +- **注册账号**: 跳转到注册页面 +- **其它方式**: 预留更多登录方式接口 + +## 使用方法 + +### 1. 访问密码登录页面 +``` +http://localhost:8080/password-login +``` + +### 2. 登录流程 +1. 输入账号(用户名、手机号或邮箱) +2. 输入密码(最少6位) +3. 勾选"我已阅读并同意《用户服务协议》及《隐私政策》" +4. 点击"登录"按钮 +5. 登录成功后自动跳转到首页 + +### 3. 其他功能 +- **密码显示**: 点击密码框右侧眼睛图标切换显示/隐藏 +- **其他登录方式**: 点击下方登录方式选项 +- **服务链接**: 点击底部服务链接 + +## 技术实现 + +### 组件结构 +``` +PasswordLogin.vue +├── 状态栏 (status-bar) +├── 头部导航 (header-bar) +├── 语言选择 (language-selector) +├── 主要内容 (main-content) +│ ├── 应用标题 (app-title) +│ ├── 登录表单 (login-form) +│ │ ├── 账号输入框 (input-group) +│ │ ├── 密码输入框 (input-group) +│ │ └── 协议同意 (agreement-section) +│ ├── 其他登录方式 (alternative-login) +│ ├── 底部服务 (footer-services) +│ └── 免责声明 (disclaimer) +``` + +### 核心功能 +- **表单验证**: 实时验证账号和密码格式 +- **密码安全**: 支持密码显示/隐藏切换 +- **协议管理**: 必须同意协议才能登录 +- **状态管理**: 完整的加载和错误状态 + +### 登录验证 +- **模拟验证**: 开发环境使用模拟验证 +- **测试账号**: admin/123456(开发环境) +- **密码强度**: 最少6位密码要求 +- **错误处理**: 详细的错误信息提示 + +## 开发说明 + +### 模拟功能 +当前使用模拟登录验证,实际项目中需要: +1. 连接真实用户认证API +2. 实现密码加密传输 +3. 添加记住密码功能 +4. 集成单点登录(SSO) + +### 验证规则 +- **账号格式**: 支持用户名、手机号、邮箱 +- **密码强度**: 最少6位,建议包含字母和数字 +- **协议同意**: 必须勾选协议才能登录 +- **登录状态**: 已登录用户访问会跳转到首页 + +### 自定义配置 +可以在 `PasswordLogin.vue` 中修改: +- 密码最小长度 +- 账号格式验证 +- 错误提示信息 +- 样式和主题 + +## 测试方法 + +### 1. 基本功能测试 +1. 访问 http://localhost:8080/password-login +2. 输入账号(如:admin) +3. 输入密码(如:123456) +4. 勾选协议同意 +5. 点击"登录" + +### 2. 验证测试 +1. 输入空账号 +2. 应该显示"请输入账号"错误 +3. 输入空密码 +4. 应该显示"请输入密码"错误 +5. 输入短密码(如:123) +6. 应该显示"密码长度不能少于6位"错误 + +### 3. 协议测试 +1. 不勾选协议同意 +2. 登录按钮应该被禁用 +3. 勾选协议同意 +4. 登录按钮应该可用 + +## 注意事项 + +1. **协议同意**: 必须同意用户服务协议和隐私政策 +2. **密码安全**: 支持密码显示/隐藏切换 +3. **登录状态**: 已登录用户访问会跳转到首页 +4. **错误处理**: 所有错误都有相应的用户提示 +5. **多种登录**: 支持多种登录方式切换 + +## 扩展功能 + +可以添加的功能: +- 记住密码 +- 自动登录 +- 忘记密码 +- 第三方登录(微信、QQ、支付宝等) +- 生物识别登录 +- 多因素认证 +- 单点登录(SSO) + +## 样式特点 + +- **移动优先**: 响应式设计,适配各种屏幕 +- **交互反馈**: 按钮状态、输入框焦点效果 +- **视觉层次**: 清晰的信息层级 +- **品牌一致**: 与整体应用风格保持一致 +- **无障碍**: 支持键盘导航和屏幕阅读器 + +## 页面跳转 + +- **从登录页**: 点击"其它"跳转到密码登录页 +- **一键登录**: 点击"一键登录"跳转到一键登录页 +- **短信登录**: 点击"短信登录"跳转到短信登录页 +- **注册账号**: 点击"注册账号"跳转到注册页 +- **返回上一页**: 点击左上角房子图标 + +## 登录方式对比 + +| 登录方式 | 页面地址 | 特点 | 适用场景 | +|---------|---------|------|---------| +| 一键登录 | /login | 简单快速 | 首次使用 | +| 短信登录 | /sms-login | 安全可靠 | 忘记密码 | +| 密码登录 | /password-login | 传统方式 | 日常使用 | +| 注册账号 | /register | 新用户 | 首次注册 | + +## 安全建议 + +1. **密码强度**: 建议使用强密码 +2. **定期更换**: 定期更换密码 +3. **安全环境**: 在安全环境下登录 +4. **退出登录**: 使用完毕后及时退出 +5. **协议阅读**: 仔细阅读用户协议和隐私政策 diff --git a/mini_program/farm-monitor-dashboard/REGISTER_PAGE_README.md b/mini_program/farm-monitor-dashboard/REGISTER_PAGE_README.md new file mode 100644 index 0000000..79a33cc --- /dev/null +++ b/mini_program/farm-monitor-dashboard/REGISTER_PAGE_README.md @@ -0,0 +1,162 @@ +# 注册账号页面使用说明 + +## 页面地址 +- **注册页面**: http://localhost:8080/register +- **登录页面**: http://localhost:8080/login +- **短信登录**: http://localhost:8080/sms-login +- **首页**: http://localhost:8080/ + +## 功能特点 + +### 🎨 界面设计 +- **简洁美观**: 采用白色背景,绿色主题色 +- **响应式设计**: 适配手机、平板、桌面等不同设备 +- **状态栏**: 显示时间、信号、WiFi、电池状态 +- **返回按钮**: 左上角返回按钮,支持返回上一页 + +### 📝 注册功能 +- **真实姓名**: 必填项,用于身份验证 +- **手机号**: 必填项,支持中国大陆手机号格式 +- **验证码**: 6位数字验证码,60秒倒计时 +- **密码**: 最少6位,支持显示/隐藏切换 +- **实时验证**: 输入格式实时验证和错误提示 + +### 🔐 安全机制 +- **手机号检查**: 验证手机号是否已注册 +- **验证码验证**: 短信验证码验证 +- **密码强度**: 最少6位密码要求 +- **重复注册检查**: 防止重复注册 +- **自动登录**: 注册成功后自动登录 + +## 使用方法 + +### 1. 访问注册页面 +``` +http://localhost:8080/register +``` + +### 2. 注册流程 +1. 输入真实姓名(必填) +2. 输入手机号(支持1[3-9]xxxxxxxxx格式) +3. 点击"发送验证码"按钮 +4. 等待60秒倒计时结束 +5. 输入收到的6位验证码 +6. 输入密码(最少6位) +7. 点击"确认"按钮 +8. 注册成功后自动登录并跳转到首页 + +### 3. 其他功能 +- **已有账号登录**: 点击"已有账号?立即登录"跳转到登录页 +- **密码显示**: 点击密码框右侧眼睛图标切换显示/隐藏 + +## 技术实现 + +### 组件结构 +``` +Register.vue +├── 状态栏 (status-bar) +├── 头部导航 (header-bar) +├── 主要内容 (main-content) +│ ├── 注册表单 (register-form) +│ │ ├── 真实姓名输入框 (input-group) +│ │ ├── 手机号输入框 (input-group) +│ │ ├── 验证码输入框 (input-group) +│ │ └── 密码输入框 (input-group) +│ └── 其他选项 (alternative-options) +``` + +### 核心功能 +- **表单验证**: 实时验证所有输入字段 +- **倒计时管理**: 60秒发送间隔保护 +- **API集成**: 集成用户注册和短信服务API +- **状态管理**: 完整的加载和错误状态 + +### 用户服务API +- **用户注册**: `POST /api/user/register` +- **检查手机号**: `GET /api/user/check-phone/{phone}` +- **检查用户名**: `GET /api/user/check-username/{username}` +- **获取用户信息**: `GET /api/user/{userId}` +- **更新用户信息**: `PUT /api/user/{userId}` +- **修改密码**: `POST /api/user/{userId}/change-password` +- **重置密码**: `POST /api/user/reset-password` + +## 开发说明 + +### 模拟功能 +当前使用模拟注册服务,实际项目中需要: +1. 连接真实用户注册API +2. 实现用户数据存储 +3. 添加邮箱验证功能 +4. 集成实名认证服务 + +### 验证规则 +- **真实姓名**: 不能为空,支持中文和英文 +- **手机号**: 中国大陆手机号格式(1[3-9]xxxxxxxxx) +- **验证码**: 6位数字,5分钟有效期 +- **密码**: 最少6位,支持字母数字组合 + +### 自定义配置 +可以在 `Register.vue` 中修改: +- 密码最小长度 +- 验证码长度和格式 +- 错误提示信息 +- 样式和主题 + +## 测试方法 + +### 1. 基本功能测试 +1. 访问 http://localhost:8080/register +2. 输入真实姓名(如:张三) +3. 输入手机号(如:13800138000) +4. 点击"发送验证码" +5. 输入任意6位数字(如:123456) +6. 输入密码(如:123456) +7. 点击"确认" + +### 2. 验证测试 +1. 输入空真实姓名 +2. 应该显示"请输入真实姓名"错误 +3. 输入无效手机号(如:123) +4. 应该显示"请输入正确的手机号"错误 +5. 输入短密码(如:123) +6. 应该显示"密码长度不能少于6位"错误 + +### 3. 重复注册测试 +1. 使用已注册的手机号 +2. 应该显示"该手机号已注册,请直接登录"错误 + +## 注意事项 + +1. **真实姓名**: 必须输入真实姓名,用于身份验证 +2. **手机号格式**: 支持中国大陆手机号格式 +3. **验证码长度**: 必须输入6位数字 +4. **密码强度**: 最少6位,建议包含字母和数字 +5. **重复注册**: 已注册手机号不能重复注册 +6. **自动登录**: 注册成功后自动登录并跳转 + +## 扩展功能 + +可以添加的功能: +- 邮箱注册选项 +- 实名认证集成 +- 头像上传 +- 用户协议同意 +- 邀请码注册 +- 第三方注册(微信、QQ等) +- 密码强度检测 +- 图形验证码 + +## 样式特点 + +- **移动优先**: 响应式设计,适配各种屏幕 +- **交互反馈**: 按钮状态、输入框焦点效果 +- **视觉层次**: 清晰的信息层级 +- **品牌一致**: 与整体应用风格保持一致 +- **无障碍**: 支持键盘导航和屏幕阅读器 + +## 页面跳转 + +- **从登录页**: 点击"注册账号"跳转到注册页 +- **从短信登录页**: 点击"注册账号"跳转到注册页 +- **返回上一页**: 点击左上角返回按钮 +- **已有账号**: 点击"已有账号?立即登录"跳转到登录页 diff --git a/mini_program/farm-monitor-dashboard/ROUTER_FIX_README.md b/mini_program/farm-monitor-dashboard/ROUTER_FIX_README.md new file mode 100644 index 0000000..a1afa6b --- /dev/null +++ b/mini_program/farm-monitor-dashboard/ROUTER_FIX_README.md @@ -0,0 +1,107 @@ +# 路由守卫修复说明 + +## 问题描述 +出现错误:`Redirected when going from "/password-login" to "/" via a navigation guard.` + +这是由于Vue Router的导航守卫导致的无限重定向循环。 + +## 问题原因 +1. 用户从密码登录页面跳转到首页 +2. 路由守卫检测到用户已登录 +3. 路由守卫重定向到首页 +4. 形成无限循环 + +## 修复方案 + +### 1. 优化路由守卫逻辑 +```javascript +// 如果是从登录页面跳转到首页,且用户已登录,直接允许访问 +if (from.path && isLoginPage && to.path === '/' && isAuthenticated) { + console.log('允许从登录页跳转到首页') + next() + return +} +``` + +### 2. 修复异步token设置 +```javascript +// 确保token设置完成后再跳转 +await auth.setTestToken() +auth.setUserInfo(userInfo) + +// 延迟跳转,确保token设置完成 +setTimeout(() => { + this.$router.push('/') +}, 100) +``` + +### 3. 添加调试日志 +```javascript +console.log('路由守卫:', { + from: from.path, + to: to.path, + requiresAuth, + isLoginPage, + isAuthenticated +}) +``` + +## 修复的文件 + +### 1. `src/router/index.js` +- 添加了特殊处理逻辑,允许从登录页跳转到首页 +- 添加了详细的调试日志 +- 优化了路由守卫的条件判断 + +### 2. `src/components/PasswordLogin.vue` +- 修复了异步token设置问题 +- 添加了延迟跳转机制 + +### 3. `src/components/SmsLogin.vue` +- 修复了异步token设置问题 + +### 4. `src/components/Register.vue` +- 修复了异步token设置问题 +- 添加了延迟跳转机制 + +## 测试方法 + +1. 访问 `http://localhost:8080/password-login` +2. 输入任意账号和密码(如:admin/123456) +3. 点击登录按钮 +4. 应该能正常跳转到首页,不再出现重定向错误 + +## 预期结果 + +- ✅ 登录成功后正常跳转到首页 +- ✅ 不再出现路由重定向错误 +- ✅ 控制台显示详细的路由守卫日志 +- ✅ 所有登录方式都能正常工作 + +## 调试信息 + +在浏览器控制台中可以看到: +``` +路由守卫: { + from: "/password-login", + to: "/", + requiresAuth: true, + isLoginPage: true, + isAuthenticated: true +} +允许从登录页跳转到首页 +``` + +## 注意事项 + +1. 确保所有登录页面都使用 `await auth.setTestToken()` +2. 跳转前添加适当的延迟 +3. 路由守卫的逻辑要避免循环重定向 +4. 添加足够的调试日志帮助排查问题 + +## 如果问题仍然存在 + +1. 清除浏览器缓存和localStorage +2. 检查控制台是否有其他错误 +3. 确认token设置是否成功 +4. 查看路由守卫的详细日志 diff --git a/mini_program/farm-monitor-dashboard/SEARCH_FUNCTIONALITY.md b/mini_program/farm-monitor-dashboard/SEARCH_FUNCTIONALITY.md new file mode 100644 index 0000000..ecd2892 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/SEARCH_FUNCTIONALITY.md @@ -0,0 +1,175 @@ +# 智能耳标搜索功能说明 + +## 功能概述 + +智能耳标搜索功能提供了精确和模糊两种搜索模式,支持根据耳标编号进行快速查找。 + +## 搜索特性 + +### 1. 精确搜索 +- **触发条件**: 输入完整的耳标编号(如:2105517333) +- **搜索逻辑**: 完全匹配 `cid` 字段 +- **结果**: 返回唯一匹配的设备 + +### 2. 模糊搜索 +- **触发条件**: 输入部分耳标编号或其他字段 +- **搜索字段**: + - `cid` (耳标编号) + - `earTagId` (备用耳标编号) + - `collectedHost` (被采集主机) + - `sid` (备用采集主机) +- **结果**: 返回包含搜索关键词的所有设备 + +## 用户界面 + +### 搜索区域 +``` +┌─────────────────────────────────────┐ +│ 🔍 [搜索框] [+] │ +└─────────────────────────────────────┘ +``` + +### 搜索状态显示 +``` +┌─────────────────────────────────────┐ +│ 搜索中... [清除搜索] │ +└─────────────────────────────────────┘ +``` + +## 技术实现 + +### 1. 搜索状态管理 +```javascript +data() { + return { + searchQuery: '', // 搜索关键词 + isSearching: false, // 是否正在搜索 + searchResults: [], // 搜索结果 + originalDevices: [], // 原始设备数据 + searchTimeout: null // 搜索延迟定时器 + } +} +``` + +### 2. 实时搜索 +```javascript +handleSearchInput() { + // 500ms延迟,避免频繁搜索 + clearTimeout(this.searchTimeout) + this.searchTimeout = setTimeout(() => { + this.performSearch() + }, 500) +} +``` + +### 3. 精确搜索逻辑 +```javascript +// 精确匹配耳标编号 +const exactMatch = this.originalDevices.find(device => + device.cid && device.cid.toString() === searchQuery +) + +if (exactMatch) { + this.searchResults = [exactMatch] + console.log('找到精确匹配的耳标:', exactMatch.cid) +} +``` + +### 4. 模糊搜索逻辑 +```javascript +// 模糊搜索多个字段 +this.searchResults = this.originalDevices.filter(device => + (device.cid && device.cid.toString().includes(searchQuery)) || + (device.earTagId && device.earTagId.includes(searchQuery)) || + (device.collectedHost && device.collectedHost.includes(searchQuery)) || + (device.sid && device.sid.includes(searchQuery)) +) +``` + +## 搜索流程 + +### 1. 用户输入 +- 用户在搜索框中输入关键词 +- 系统检测到输入变化 + +### 2. 延迟搜索 +- 等待500ms,避免频繁搜索 +- 如果用户继续输入,取消之前的搜索 + +### 3. 执行搜索 +- 检查输入是否为空 +- 如果为空,清除搜索状态 +- 如果不为空,执行搜索逻辑 + +### 4. 显示结果 +- 精确匹配:显示单个设备 +- 模糊匹配:显示多个设备 +- 无匹配:显示空列表 + +### 5. 清除搜索 +- 点击"清除搜索"按钮 +- 恢复原始设备列表 +- 重置分页状态 + +## 搜索优化 + +### 1. 性能优化 +- **延迟搜索**: 500ms延迟避免频繁请求 +- **本地搜索**: 基于已加载的数据进行搜索 +- **状态缓存**: 保存原始数据避免重复加载 + +### 2. 用户体验 +- **实时反馈**: 搜索状态实时显示 +- **键盘支持**: 支持Enter键触发搜索 +- **一键清除**: 快速清除搜索状态 + +### 3. 错误处理 +- **空输入处理**: 自动清除搜索状态 +- **异常捕获**: 搜索失败时显示错误信息 +- **状态恢复**: 搜索失败时恢复原始状态 + +## 使用示例 + +### 精确搜索 +1. 在搜索框输入:`2105517333` +2. 系统找到精确匹配的设备 +3. 显示该设备的详细信息 + +### 模糊搜索 +1. 在搜索框输入:`210551` +2. 系统找到所有包含该数字的设备 +3. 显示匹配的设备列表 + +### 清除搜索 +1. 点击"清除搜索"按钮 +2. 恢复显示所有设备 +3. 重置分页到第一页 + +## 技术细节 + +### 数据流 +``` +用户输入 → 延迟处理 → 精确搜索 → 模糊搜索 → 显示结果 + ↓ +清除搜索 ← 恢复原始数据 ← 重置状态 +``` + +### 状态管理 +- `isSearching`: 控制搜索状态显示 +- `searchResults`: 存储搜索结果 +- `originalDevices`: 保存原始数据 +- `searchTimeout`: 管理搜索延迟 + +### 事件处理 +- `@input`: 实时输入处理 +- `@keyup.enter`: 回车键搜索 +- `@click`: 按钮点击事件 + +## 扩展功能 + +### 未来可扩展的搜索功能 +1. **高级搜索**: 支持多条件组合搜索 +2. **搜索历史**: 保存常用搜索关键词 +3. **搜索建议**: 输入时显示搜索建议 +4. **搜索过滤**: 按设备状态、类型等过滤 +5. **搜索统计**: 显示搜索结果统计信息 diff --git a/mini_program/farm-monitor-dashboard/SMS_LOGIN_README.md b/mini_program/farm-monitor-dashboard/SMS_LOGIN_README.md new file mode 100644 index 0000000..f6e4bd0 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/SMS_LOGIN_README.md @@ -0,0 +1,139 @@ +# 短信登录页面使用说明 + +## 页面地址 +- **短信登录页面**: http://localhost:8080/sms-login +- **普通登录页面**: http://localhost:8080/login +- **首页**: http://localhost:8080/ + +## 功能特点 + +### 🎨 界面设计 +- **简洁美观**: 采用白色背景,绿色主题色 +- **响应式设计**: 适配手机、平板、桌面等不同设备 +- **状态栏**: 显示时间、信号、WiFi、电池状态 +- **返回按钮**: 左上角返回按钮,支持返回上一页 + +### 📱 短信登录功能 +- **账号输入**: 支持手机号或用户名登录 +- **验证码发送**: 60秒倒计时,防止频繁发送 +- **实时验证**: 输入格式实时验证 +- **错误提示**: 详细的错误信息提示 + +### 🔐 安全机制 +- **手机号验证**: 检查手机号是否已注册 +- **验证码验证**: 6位数字验证码验证 +- **倒计时保护**: 防止频繁发送验证码 +- **路由保护**: 未登录用户自动跳转 + +## 使用方法 + +### 1. 访问短信登录页面 +``` +http://localhost:8080/sms-login +``` + +### 2. 登录流程 +1. 输入手机号或账号(支持手机号格式:1[3-9]xxxxxxxxx) +2. 点击"发送验证码"按钮 +3. 等待60秒倒计时结束 +4. 输入收到的6位验证码 +5. 点击"登录"按钮 +6. 登录成功后自动跳转到首页 + +### 3. 其他功能 +- **密码登录**: 点击"密码登录"跳转到普通登录页 +- **注册账号**: 点击"注册账号"(功能开发中) + +## 技术实现 + +### 组件结构 +``` +SmsLogin.vue +├── 状态栏 (status-bar) +├── 头部导航 (header-bar) +├── 主要内容 (main-content) +│ ├── 应用标题 (app-title) +│ ├── 登录表单 (login-form) +│ │ ├── 账号输入框 (input-group) +│ │ └── 验证码输入框 (input-group) +│ └── 其他登录方式 (alternative-login) +``` + +### 核心功能 +- **表单验证**: 实时验证输入格式 +- **倒计时管理**: 60秒发送间隔保护 +- **API集成**: 集成短信服务API +- **状态管理**: 完整的加载和错误状态 + +### 短信服务API +- **发送验证码**: `POST /api/sms/send` +- **验证验证码**: `POST /api/sms/verify` +- **检查手机号**: `GET /api/user/check-phone/{phone}` +- **获取发送记录**: `GET /api/sms/history/{phone}` + +## 开发说明 + +### 模拟功能 +当前使用模拟短信服务,实际项目中需要: +1. 连接真实短信服务商(如阿里云、腾讯云) +2. 实现验证码存储和过期机制 +3. 添加发送频率限制 +4. 集成用户注册检查 + +### 验证码规则 +- **长度**: 6位数字 +- **有效期**: 5分钟 +- **发送间隔**: 60秒 +- **格式验证**: 手机号格式验证 + +### 自定义配置 +可以在 `SmsLogin.vue` 中修改: +- 验证码长度和格式 +- 倒计时时间 +- 错误提示信息 +- 样式和主题 + +## 测试方法 + +### 1. 基本功能测试 +1. 访问 http://localhost:8080/sms-login +2. 输入手机号(如:13800138000) +3. 点击"发送验证码" +4. 输入任意6位数字(如:123456) +5. 点击"登录" + +### 2. 验证测试 +1. 输入无效手机号(如:123) +2. 应该显示格式错误提示 +3. 输入空验证码 +4. 应该显示验证码错误提示 + +### 3. 倒计时测试 +1. 发送验证码后 +2. 按钮应该显示"60s后重发" +3. 倒计时结束后恢复"发送验证码" + +## 注意事项 + +1. **手机号格式**: 支持中国大陆手机号格式 +2. **验证码长度**: 必须输入6位数字 +3. **发送间隔**: 60秒内不能重复发送 +4. **登录状态**: 已登录用户访问会跳转到首页 +5. **错误处理**: 所有错误都有相应的用户提示 + +## 扩展功能 + +可以添加的功能: +- 图形验证码 +- 语音验证码 +- 国际手机号支持 +- 记住手机号 +- 自动填充验证码 +- 生物识别登录 + +## 样式特点 + +- **移动优先**: 响应式设计,适配各种屏幕 +- **交互反馈**: 按钮状态、输入框焦点效果 +- **视觉层次**: 清晰的信息层级 +- **品牌一致**: 与整体应用风格保持一致 diff --git a/mini_program/farm-monitor-dashboard/SYNTAX_ERROR_FIX.md b/mini_program/farm-monitor-dashboard/SYNTAX_ERROR_FIX.md new file mode 100644 index 0000000..0bd9bbd --- /dev/null +++ b/mini_program/farm-monitor-dashboard/SYNTAX_ERROR_FIX.md @@ -0,0 +1,60 @@ +# Vue模板语法错误修复 + +## 问题描述 +编译时出现Vue模板语法错误: +``` +SyntaxError: Unexpected token (1:7333) +``` + +## 问题原因 +Vue 2不支持ES2020的可选链操作符(`?.`),在模板中使用了: +```vue +{{ selectedDevice?.eartagNumber || selectedDevice?.earTagId }} +``` + +## 解决方案 +将可选链操作符替换为Vue 2兼容的语法: + +### 修复前 +```vue +

确定要删除设备 "{{ selectedDevice?.eartagNumber || selectedDevice?.earTagId }}" 吗?

+``` + +### 修复后 +```vue +

确定要删除设备 "{{ (selectedDevice && selectedDevice.eartagNumber) || (selectedDevice && selectedDevice.earTagId) || '未知设备' }}" 吗?

+``` + +## 技术说明 + +### Vue 2兼容性 +- Vue 2使用较旧的JavaScript语法解析器 +- 不支持ES2020的可选链操作符(`?.`) +- 不支持空值合并操作符(`??`) + +### 替代方案 +使用逻辑与操作符(`&&`)进行安全的属性访问: +```javascript +// 不兼容Vue 2 +obj?.prop?.subprop + +// Vue 2兼容 +obj && obj.prop && obj.prop.subprop +``` + +## 验证结果 +- ✅ 语法错误已修复 +- ✅ 前端服务正常启动 +- ✅ 编译成功无错误 +- ✅ 功能正常工作 + +## 预防措施 +1. 在Vue 2项目中避免使用ES2020+语法 +2. 使用Babel转译器处理现代JavaScript语法 +3. 在模板中使用Vue 2兼容的表达式 +4. 定期检查编译错误和警告 + +## 相关文件 +- `src/components/EarTag.vue` - 修复的文件 +- Vue 2.6.14 - 当前使用的Vue版本 +- vue-template-compiler - 模板编译器版本 diff --git a/mini_program/farm-monitor-dashboard/TOKEN_ERROR_FIX.md b/mini_program/farm-monitor-dashboard/TOKEN_ERROR_FIX.md new file mode 100644 index 0000000..9b6fbee --- /dev/null +++ b/mini_program/farm-monitor-dashboard/TOKEN_ERROR_FIX.md @@ -0,0 +1,141 @@ +# Token错误修复说明 + +## 问题描述 +出现错误:`无法通过API获取测试token,使用模拟token: Cannot read properties of undefined (reading 'token')` + +## 问题原因 +1. API响应结构与预期不符 +2. 前端代理可能没有正确工作 +3. 网络连接问题 + +## 修复方案 + +### 1. 修复API响应处理 +```javascript +// 修复前 +if (response.success && response.data.token) { + +// 修复后 +if (response && response.success && response.token) { +``` + +### 2. 添加现有token检查 +```javascript +// 首先检查是否已经有有效的token +const existingToken = this.getToken() +if (existingToken && existingToken.startsWith('eyJ')) { + console.log('使用现有JWT token') + return existingToken +} +``` + +### 3. 添加手动设置真实token的方法 +```javascript +setRealToken() { + const realToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' + this.setToken(realToken) + return realToken +} +``` + +### 4. 增强错误处理 +- 添加详细的日志输出 +- 优雅处理API调用失败 +- 提供备用方案 + +## 使用方法 + +### 方法1:使用认证测试页面 +1. 访问 `http://localhost:8080/auth-test` +2. 点击"设置真实Token"按钮 +3. 点击"测试所有API"按钮 + +### 方法2:手动设置token +在浏览器控制台中执行: +```javascript +// 设置真实token +localStorage.setItem('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20iLCJpYXQiOjE3NTgxODM3NjEsImV4cCI6MTc1ODI3MDE2MX0.J3DD78bULP1pe5DMF2zbQEMFzeytV6uXgOuDIKOPww0') + +// 设置用户信息 +localStorage.setItem('userInfo', JSON.stringify({ + id: 'user-001', + name: '爱农智慧牧场用户', + account: 'admin', + role: 'user' +})) +``` + +### 方法3:直接访问API获取token +```powershell +$response = Invoke-WebRequest -Uri "http://localhost:5350/api/auth/login" -Method POST -Body '{"username":"admin","password":"123456"}' -ContentType "application/json" +$token = ($response.Content | ConvertFrom-Json).token +Write-Host "Token: $token" +``` + +## 测试步骤 + +1. 清除浏览器缓存和localStorage +2. 访问认证测试页面 +3. 点击"设置真实Token" +4. 点击"测试所有API" +5. 查看测试结果 + +## 预期结果 + +- ✅ 成功设置真实JWT token +- ✅ 所有API调用成功 +- ✅ 获取到真实的设备数据 +- ✅ 不再出现token相关错误 + +## 故障排除 + +### 如果仍然出现错误 +1. 检查后端服务是否运行在 `http://localhost:5350` +2. 检查前端代理配置 +3. 清除浏览器缓存 +4. 使用手动设置token的方法 + +### 如果API调用失败 +1. 检查网络连接 +2. 检查CORS设置 +3. 查看浏览器控制台错误 +4. 使用直接API调用测试 + +## 技术细节 + +### API响应结构 +```json +{ + "success": true, + "message": "登录成功", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "user": { + "id": 1, + "username": "admin", + "email": "admin@example.com" + } +} +``` + +### Token格式 +- JWT token以 `eyJ` 开头 +- 包含用户ID、用户名、邮箱等信息 +- 有效期为24小时 + +### 代理配置 +```javascript +// vue.config.js +proxy: { + '/api': { + target: 'http://localhost:5350', + changeOrigin: true + } +} +``` + +## 下一步 + +1. 修复前端代理问题 +2. 实现token自动刷新 +3. 添加更好的错误处理 +4. 优化用户体验 diff --git a/mini_program/farm-monitor-dashboard/package-lock.json b/mini_program/farm-monitor-dashboard/package-lock.json index 79b71d6..0d71cb5 100644 --- a/mini_program/farm-monitor-dashboard/package-lock.json +++ b/mini_program/farm-monitor-dashboard/package-lock.json @@ -8,20 +8,26 @@ "name": "farm-mini-program", "version": "1.0.0", "dependencies": { - "@vant/weapp": "^1.11.6", + "@dcloudio/uni-app": "^2.0.2-alpha-4080120250905001", + "@vue/composition-api": "^1.4.0", "axios": "^0.27.2", "dayjs": "^1.11.0", "pinia": "^2.1.6", - "vue": "^3.3.4" + "vue": "^2.6.14", + "vue-router": "^3.6.5", + "vue-template-compiler": "^2.6.14" }, "devDependencies": { - "@dcloudio/uni-cli-shared": "^3.0.0-alpha-4070620250731002", - "@dcloudio/uni-h5": "^3.0.0-alpha-4070620250731002", - "@dcloudio/uni-mp-weixin": "^3.0.0-alpha-4070620250731002", + "@dcloudio/uni-cli-shared": "^2.0.2-alpha-4080120250905001", + "@dcloudio/uni-h5": "^2.0.2-alpha-4080120250905001", + "@dcloudio/uni-mp-weixin": "^2.0.2-alpha-4080120250905001", + "@vant/weapp": "^1.11.7", "@vue/cli-service": "^5.0.8", "cross-env": "^7.0.3", "eslint": "^8.45.0", "eslint-plugin-vue": "^9.15.0", + "sass": "^1.92.1", + "sass-loader": "^16.0.5", "typescript": "^5.1.0" }, "engines": { @@ -43,19 +49,6 @@ "node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21 || 22" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.24.7.tgz", @@ -78,80 +71,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator/node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.28.4" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/generator/node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", @@ -168,70 +87,11 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports/node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "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.27.1", "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -245,32 +105,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/highlight": { "version": "7.25.9", "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.25.9.tgz", @@ -286,707 +120,93 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", - "dependencies": { - "@babel/types": "^7.25.6" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } + "node_modules/@dcloudio/types": { + "version": "3.4.21", + "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.4.21.tgz", + "integrity": "sha512-rsv3XfAaD/dtuVboPeYh+vPcULnWyozGaGKHWyN0dYRm7L1uypFUM30qNYMj9iNmbAENuBjV177S1gNEBIvdDA==", + "peer": true }, - "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template/node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.28.4" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template/node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template/node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "node_modules/@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.28.4" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" + "node_modules/@dcloudio/uni-app": { + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app/-/uni-app-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-h9Og8v85U3hOBh5FCbnmmGPzX8OTJssJvQxZzi01J6lbWrqxnuP/DS+8zFb+A2mGgpzzeK/KHv9i4mUsVNv4TA==", + "peerDependencies": { + "@dcloudio/types": "^3.0.15", + "@vue/composition-api": "^1.7.0" } }, "node_modules/@dcloudio/uni-cli-shared": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-l+PR5c3clanpEgkFzuWkrpH0b74QhSmoe8eJs3RNe8BCb8ttRR7mSt+dndttEXz5aCKG1J/gt75U8oLNshy3VA==", + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-+zHK6mxN+2PcVUk7SJkrY6mXO0pk65ghJgYEoElF3UT4M0TPRe+bc3tFhTn7hGSYxP1JYx8I0RoxkIeTMDK0xA==", "dev": true, "dependencies": { - "@ampproject/remapping": "^2.1.2", - "@babel/code-frame": "7.24.7", - "@babel/core": "7.25.2", - "@babel/parser": "7.25.6", - "@babel/types": "7.25.6", - "@dcloudio/uni-i18n": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@intlify/core-base": "9.1.9", - "@intlify/shared": "9.1.9", - "@intlify/vue-devtools": "9.1.9", - "@rollup/pluginutils": "5.1.0", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/compiler-ssr": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21", - "adm-zip": "0.5.16", - "autoprefixer": "10.4.20", - "base64url": "^3.0.1", - "chokidar": "3.6.0", - "compare-versions": "^3.6.0", - "debug": "4.3.7", - "entities": "^4.5.0", - "es-module-lexer": "1.5.4", - "esbuild": "0.20.2", - "estree-walker": "2.0.2", - "fast-glob": "3.3.3", - "fs-extra": "10.1.0", - "hash-sum": "2.0.0", - "isbinaryfile": "5.0.2", - "jsonc-parser": "3.3.1", - "lines-and-columns": "^2.0.4", - "magic-string": "0.30.11", - "merge": "2.1.1", - "mime": "3.0.0", - "module-alias": "2.2.3", - "os-locale-s-fix": "^1.0.8-fix-1", - "picocolors": "1.1.0", - "postcss-import": "^14.0.2", - "postcss-load-config": "^3.1.1", - "postcss-modules": "^4.3.0", - "postcss-selector-parser": "6.1.2", - "resolve": "1.22.8", - "source-map-js": "1.2.1", - "tapable": "^2.2.0", - "unimport": "4.1.1", - "unplugin-auto-import": "19.1.0", - "xregexp": "3.1.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" + "escape-string-regexp": "^4.0.0", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.0", + "glob-escape": "^0.0.2", + "hash-sum": "^1.0.2", + "postcss-urlrewrite": "^0.2.2", + "strip-json-comments": "^2.0.1" } }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", - "dev": true, - "dependencies": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "vue": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "node_modules/@dcloudio/uni-cli-shared/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/unplugin-auto-import": { - "version": "19.1.0", - "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-19.1.0.tgz", - "integrity": "sha512-B+TGBEBHqY9aR+7YfShfLujETOHstzpV+yaqgy5PkfV0QG7Py+TYMX7vJ9W4SrysHR+UzR+gzcx/nuZjmPeclA==", + "node_modules/@dcloudio/uni-cli-shared/node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", + "dev": true + }, + "node_modules/@dcloudio/uni-cli-shared/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, - "dependencies": { - "local-pkg": "^1.0.0", - "magic-string": "^0.30.17", - "picomatch": "^4.0.2", - "unimport": "^4.1.1", - "unplugin": "^2.2.0", - "unplugin-utils": "^0.2.4" - }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@nuxt/kit": "^3.2.2", - "@vueuse/core": "*" - }, - "peerDependenciesMeta": { - "@nuxt/kit": { - "optional": true - }, - "@vueuse/core": { - "optional": true - } - } - }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/unplugin-auto-import/node_modules/magic-string": { - "version": "0.30.19", - "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz", - "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/@dcloudio/uni-cli-shared/node_modules/vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=0.10.0" } }, "node_modules/@dcloudio/uni-h5": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-eiFmQpxCAAVPdeC0gyZuCtNJJtMNoie6T7ao2U8Ucxn1I6uXrpzWyP2nusuqtAzd0JgRgo/6T8xUZjOw2C9OhQ==", + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-hQ1ONQm+8ZKnc6FRbRT9xWGwH4ed0KqVIgvwduG7bVnvcvhxIuFhPUthMCYyvQaVjdp0yjBiUicVEwomWSsZRw==", "dev": true, "dependencies": { - "@dcloudio/uni-h5-vite": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-h5-vue": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-i18n": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21", - "debug": "4.3.7", - "localstorage-polyfill": "^1.0.1", - "postcss-selector-parser": "6.1.2", - "safe-area-insets": "1.4.1", - "vue-router": "4.4.4", - "xmlhttprequest": "^1.8.0" + "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/@dcloudio/uni-h5-vite": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vite/-/uni-h5-vite-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-jQ1rqXyjUR0j8Lvfbbjtvr5tiqTVXbk04qSzWzI8s36CO9ljNlAsTkd1tPxGlZNLKj6Ag1glwSvqaVzimPHuqw==", + "node_modules/@dcloudio/uni-h5/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==", "dev": true, "dependencies": { - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@rollup/pluginutils": "5.1.0", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21", - "debug": "4.3.7", - "fs-extra": "10.1.0", - "mime": "3.0.0", - "module-alias": "2.2.3" - } - }, - "node_modules/@dcloudio/uni-h5-vite/node_modules/@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5-vite/node_modules/@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5-vite/node_modules/@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "node_modules/@dcloudio/uni-h5-vite/node_modules/@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", - "dev": true, - "dependencies": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "vue": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5-vite/node_modules/vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@dcloudio/uni-h5-vue": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vue/-/uni-h5-vue-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-x16jzybDQAIFtq/uou+t4qyH93WBpC6QGF3CCQ1QF5YzwFtmzw52sFII2cjsjPxgad4+WpdQhQM4eu6a2l3HEw==", - "dev": true, - "dependencies": { - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/server-renderer": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5-vue/node_modules/@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5-vue/node_modules/@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5-vue/node_modules/@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "node_modules/@dcloudio/uni-h5-vue/node_modules/@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", - "dev": true, - "dependencies": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "vue": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5-vue/node_modules/vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@dcloudio/uni-h5/node_modules/@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5/node_modules/@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5/node_modules/@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "node_modules/@dcloudio/uni-h5/node_modules/@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", - "dev": true, - "dependencies": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "vue": "3.4.21" - } - }, - "node_modules/@dcloudio/uni-h5/node_modules/vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@dcloudio/uni-i18n": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-i18n/-/uni-i18n-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-7nscVrmAhhBkLkEDOa4+fXceOT7vp1DnPQZfepqeP5enmsA+L3sQpmyl78UG0i4ZHcVGLaqmPrQgWqg3MgmJVQ==", - "dev": true - }, - "node_modules/@dcloudio/uni-mp-compiler": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-compiler/-/uni-mp-compiler-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-Gua1gqurqWf4TnKTaRbaig4JHiXqt32qyWpwQGanyqLMVVptQcMzs+Gx3pcDmTO/Kk4bEN9sZoT5nR1jMsKvKg==", - "dev": true, - "dependencies": { - "@babel/generator": "7.25.6", - "@babel/parser": "7.25.6", - "@babel/types": "7.25.6", - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/shared": "3.4.21", - "estree-walker": "2.0.2" - } - }, - "node_modules/@dcloudio/uni-mp-compiler/node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "postcss-helpers": "^0.3.3" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@dcloudio/uni-mp-compiler/node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@dcloudio/uni-mp-vite": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vite/-/uni-mp-vite-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-zfSrLT/+m+j9+Glusyb1LffgdkUhnaQD8MMK8rrDnj/90ZQlngAhYarT0968ISqxKQ0nNHk4DDvlgGmWKD0dHQ==", - "dev": true, - "dependencies": { - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-i18n": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-compiler": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-vue": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/shared": "3.4.21", - "debug": "4.3.7" - } - }, - "node_modules/@dcloudio/uni-mp-vue": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vue/-/uni-mp-vue-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-EIFwi0au3oeclW9DKB8zUawNdzyGzyxMvUyzgzcjqoiONcla4fqFfV//89g/vot+50htbsfWOecIiZrNDGiJ5w==", - "dev": true, - "dependencies": { - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/shared": "3.4.21" + "node": ">=16" } }, "node_modules/@dcloudio/uni-mp-weixin": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-weixin/-/uni-mp-weixin-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-fG5aUUtyV4IrXY1v04GYn3t5RCoYuc4lRTwrXrWwa2r/Bohtb7n0uKiPLtSjLzoz6spXcn4cXdiqg7XJQFLLWw==", - "dev": true, - "dependencies": { - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-vite": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-vue": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/shared": "3.4.21", - "jimp": "0.10.3", - "licia": "1.41.1", - "qrcode-reader": "1.0.4", - "qrcode-terminal": "0.12.0", - "ws": "8.18.0" - } - }, - "node_modules/@dcloudio/uni-shared": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-shared/-/uni-shared-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-oIWdjiUezdiXxw83zcc6USX4XC9pWM125JQdXpKpSYOwg7revpyTB1JYYY29X58RJbctyhtMJcMun7A2nj84Qg==", - "dev": true, - "dependencies": { - "@vue/shared": "3.4.21" - } + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-weixin/-/uni-mp-weixin-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-tyEt9RLhG39EBH+sgGPUJmBbJDwMcnv46CLzPChDLDVdunupqjHB42MmzUY8yrDNeZuD4MB02NAI3oLUrsSw0w==", + "dev": true }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", @@ -997,374 +217,6 @@ "node": ">=10.0.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", @@ -1474,577 +326,6 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, - "node_modules/@intlify/core-base": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz", - "integrity": "sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==", - "dev": true, - "dependencies": { - "@intlify/devtools-if": "9.1.9", - "@intlify/message-compiler": "9.1.9", - "@intlify/message-resolver": "9.1.9", - "@intlify/runtime": "9.1.9", - "@intlify/shared": "9.1.9", - "@intlify/vue-devtools": "9.1.9" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@intlify/devtools-if": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz", - "integrity": "sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==", - "dev": true, - "dependencies": { - "@intlify/shared": "9.1.9" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@intlify/message-compiler": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz", - "integrity": "sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==", - "dev": true, - "dependencies": { - "@intlify/message-resolver": "9.1.9", - "@intlify/shared": "9.1.9", - "source-map": "0.6.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@intlify/message-resolver": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz", - "integrity": "sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@intlify/runtime": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/runtime/-/runtime-9.1.9.tgz", - "integrity": "sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==", - "dev": true, - "dependencies": { - "@intlify/message-compiler": "9.1.9", - "@intlify/message-resolver": "9.1.9", - "@intlify/shared": "9.1.9" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@intlify/shared": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.1.9.tgz", - "integrity": "sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@intlify/vue-devtools": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz", - "integrity": "sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==", - "dev": true, - "dependencies": { - "@intlify/message-resolver": "9.1.9", - "@intlify/runtime": "9.1.9", - "@intlify/shared": "9.1.9" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@jimp/bmp": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/bmp/-/bmp-0.10.3.tgz", - "integrity": "sha512-keMOc5woiDmONXsB/6aXLR4Z5Q+v8lFq3EY2rcj2FmstbDMhRuGbmcBxlEgOqfRjwvtf/wOtJ3Of37oAWtVfLg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "bmp-js": "^0.1.0", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/core": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/core/-/core-0.10.3.tgz", - "integrity": "sha512-Gd5IpL3U2bFIO57Fh/OA3HCpWm4uW/pU01E75rI03BXfTdz3T+J7TwvyG1XaqsQ7/DSlS99GXtLQPlfFIe28UA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "any-base": "^1.1.0", - "buffer": "^5.2.0", - "core-js": "^3.4.1", - "exif-parser": "^0.1.12", - "file-type": "^9.0.0", - "load-bmfont": "^1.3.1", - "mkdirp": "^0.5.1", - "phin": "^2.9.1", - "pixelmatch": "^4.0.2", - "tinycolor2": "^1.4.1" - } - }, - "node_modules/@jimp/custom": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/custom/-/custom-0.10.3.tgz", - "integrity": "sha512-nZmSI+jwTi5IRyNLbKSXQovoeqsw+D0Jn0SxW08wYQvdkiWA8bTlDQFgQ7HVwCAKBm8oKkDB/ZEo9qvHJ+1gAQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/core": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "node_modules/@jimp/gif": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/gif/-/gif-0.10.3.tgz", - "integrity": "sha512-vjlRodSfz1CrUvvrnUuD/DsLK1GHB/yDZXHthVdZu23zYJIW7/WrIiD1IgQ5wOMV7NocfrvPn2iqUfBP81/WWA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "omggif": "^1.0.9" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/jpeg": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/jpeg/-/jpeg-0.10.3.tgz", - "integrity": "sha512-AAANwgUZOt6f6P7LZxY9lyJ9xclqutYJlsxt3JbriXUGJgrrFAIkcKcqv1nObgmQASSAQKYaMV9KdHjMlWFKlQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "jpeg-js": "^0.3.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-blit": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-blit/-/plugin-blit-0.10.3.tgz", - "integrity": "sha512-5zlKlCfx4JWw9qUVC7GI4DzXyxDWyFvgZLaoGFoT00mlXlN75SarlDwc9iZ/2e2kp4bJWxz3cGgG4G/WXrbg3Q==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-blur": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-blur/-/plugin-blur-0.10.3.tgz", - "integrity": "sha512-cTOK3rjh1Yjh23jSfA6EHCHjsPJDEGLC8K2y9gM7dnTUK1y9NNmkFS23uHpyjgsWFIoH9oRh2SpEs3INjCpZhQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-circle": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-circle/-/plugin-circle-0.10.3.tgz", - "integrity": "sha512-51GAPIVelqAcfuUpaM5JWJ0iWl4vEjNXB7p4P7SX5udugK5bxXUjO6KA2qgWmdpHuCKtoNgkzWU9fNSuYp7tCA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-color": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-color/-/plugin-color-0.10.3.tgz", - "integrity": "sha512-RgeHUElmlTH7vpI4WyQrz6u59spiKfVQbsG/XUzfWGamFSixa24ZDwX/yV/Ts+eNaz7pZeIuv533qmKPvw2ujg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "tinycolor2": "^1.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-contain": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-contain/-/plugin-contain-0.10.3.tgz", - "integrity": "sha512-bYJKW9dqzcB0Ihc6u7jSyKa3juStzbLs2LFr6fu8TzA2WkMS/R8h+ddkiO36+F9ILTWHP0CIA3HFe5OdOGcigw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-cover": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-cover/-/plugin-cover-0.10.3.tgz", - "integrity": "sha512-pOxu0cM0BRPzdV468n4dMocJXoMbTnARDY/EpC3ZW15SpMuc/dr1KhWQHgoQX5kVW1Wt8zgqREAJJCQ5KuPKDA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-crop": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-crop/-/plugin-crop-0.10.3.tgz", - "integrity": "sha512-nB7HgOjjl9PgdHr076xZ3Sr6qHYzeBYBs9qvs3tfEEUeYMNnvzgCCGtUl6eMakazZFCMk3mhKmcB9zQuHFOvkg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-displace": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-displace/-/plugin-displace-0.10.3.tgz", - "integrity": "sha512-8t3fVKCH5IVqI4lewe4lFFjpxxr69SQCz5/tlpDLQZsrNScNJivHdQ09zljTrVTCSgeCqQJIKgH2Q7Sk/pAZ0w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-dither": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-dither/-/plugin-dither-0.10.3.tgz", - "integrity": "sha512-JCX/oNSnEg1kGQ8ffZ66bEgQOLCY3Rn+lrd6v1jjLy/mn9YVZTMsxLtGCXpiCDC2wG/KTmi4862ysmP9do9dAQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-fisheye": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.10.3.tgz", - "integrity": "sha512-RRZb1wqe+xdocGcFtj2xHU7sF7xmEZmIa6BmrfSchjyA2b32TGPWKnP3qyj7p6LWEsXn+19hRYbjfyzyebPElQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-flip": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-flip/-/plugin-flip-0.10.3.tgz", - "integrity": "sha512-0epbi8XEzp0wmSjoW9IB0iMu0yNF17aZOxLdURCN3Zr+8nWPs5VNIMqSVa1Y62GSyiMDpVpKF/ITiXre+EqrPg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-rotate": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-gaussian": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.10.3.tgz", - "integrity": "sha512-25eHlFbHUDnMMGpgRBBeQ2AMI4wsqCg46sue0KklI+c2BaZ+dGXmJA5uT8RTOrt64/K9Wz5E+2n7eBnny4dfpQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-invert": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-invert/-/plugin-invert-0.10.3.tgz", - "integrity": "sha512-effYSApWY/FbtlzqsKXlTLkgloKUiHBKjkQnqh5RL4oQxh/33j6aX+HFdDyQKtsXb8CMd4xd7wyiD2YYabTa0g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-mask": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-mask/-/plugin-mask-0.10.3.tgz", - "integrity": "sha512-twrg8q8TIhM9Z6Jcu9/5f+OCAPaECb0eKrrbbIajJqJ3bCUlj5zbfgIhiQIzjPJ6KjpnFPSqHQfHkU1Vvk/nVw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-normalize": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-normalize/-/plugin-normalize-0.10.3.tgz", - "integrity": "sha512-xkb5eZI/mMlbwKkDN79+1/t/+DBo8bBXZUMsT4gkFgMRKNRZ6NQPxlv1d3QpRzlocsl6UMxrHnhgnXdLAcgrXw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-print": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-print/-/plugin-print-0.10.3.tgz", - "integrity": "sha512-wjRiI6yjXsAgMe6kVjizP+RgleUCLkH256dskjoNvJzmzbEfO7xQw9g6M02VET+emnbY0CO83IkrGm2q43VRyg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "load-bmfont": "^1.4.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-resize": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-resize/-/plugin-resize-0.10.3.tgz", - "integrity": "sha512-rf8YmEB1d7Sg+g4LpqF0Mp+dfXfb6JFJkwlAIWPUOR7lGsPWALavEwTW91c0etEdnp0+JB9AFpy6zqq7Lwkq6w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-rotate": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-rotate/-/plugin-rotate-0.10.3.tgz", - "integrity": "sha512-YXLlRjm18fkW9MOHUaVAxWjvgZM851ofOipytz5FyKp4KZWDLk+dZK1JNmVmK7MyVmAzZ5jsgSLhIgj+GgN0Eg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-scale": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-scale/-/plugin-scale-0.10.3.tgz", - "integrity": "sha512-5DXD7x7WVcX1gUgnlFXQa8F+Q3ThRYwJm+aesgrYvDOY+xzRoRSdQvhmdd4JEEue3lyX44DvBSgCIHPtGcEPaw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-shadow": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-shadow/-/plugin-shadow-0.10.3.tgz", - "integrity": "sha512-/nkFXpt2zVcdP4ETdkAUL0fSzyrC5ZFxdcphbYBodqD7fXNqChS/Un1eD4xCXWEpW8cnG9dixZgQgStjywH0Mg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blur": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-threshold": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-threshold/-/plugin-threshold-0.10.3.tgz", - "integrity": "sha512-Dzh0Yq2wXP2SOnxcbbiyA4LJ2luwrdf1MghNIt9H+NX7B+IWw/N8qA2GuSm9n4BPGSLluuhdAWJqHcTiREriVA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-color": ">=0.8.0", - "@jimp/plugin-resize": ">=0.8.0" - } - }, - "node_modules/@jimp/plugins": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugins/-/plugins-0.10.3.tgz", - "integrity": "sha512-jTT3/7hOScf0EIKiAXmxwayHhryhc1wWuIe3FrchjDjr9wgIGNN2a7XwCgPl3fML17DXK1x8EzDneCdh261bkw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/plugin-blit": "^0.10.3", - "@jimp/plugin-blur": "^0.10.3", - "@jimp/plugin-circle": "^0.10.3", - "@jimp/plugin-color": "^0.10.3", - "@jimp/plugin-contain": "^0.10.3", - "@jimp/plugin-cover": "^0.10.3", - "@jimp/plugin-crop": "^0.10.3", - "@jimp/plugin-displace": "^0.10.3", - "@jimp/plugin-dither": "^0.10.3", - "@jimp/plugin-fisheye": "^0.10.3", - "@jimp/plugin-flip": "^0.10.3", - "@jimp/plugin-gaussian": "^0.10.3", - "@jimp/plugin-invert": "^0.10.3", - "@jimp/plugin-mask": "^0.10.3", - "@jimp/plugin-normalize": "^0.10.3", - "@jimp/plugin-print": "^0.10.3", - "@jimp/plugin-resize": "^0.10.3", - "@jimp/plugin-rotate": "^0.10.3", - "@jimp/plugin-scale": "^0.10.3", - "@jimp/plugin-shadow": "^0.10.3", - "@jimp/plugin-threshold": "^0.10.3", - "core-js": "^3.4.1", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/png": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/png/-/png-0.10.3.tgz", - "integrity": "sha512-YKqk/dkl+nGZxSYIDQrqhmaP8tC3IK8H7dFPnnzFVvbhDnyYunqBZZO3SaZUKTichClRw8k/CjBhbc+hifSGWg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "pngjs": "^3.3.3" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/tiff": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/tiff/-/tiff-0.10.3.tgz", - "integrity": "sha512-7EsJzZ5Y/EtinkBGuwX3Bi4S+zgbKouxjt9c82VJTRJOQgLWsE/RHqcyRCOQBhHAZ9QexYmDz34medfLKdoX0g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "core-js": "^3.4.1", - "utif": "^2.0.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/types": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/types/-/types-0.10.3.tgz", - "integrity": "sha512-XGmBakiHZqseSWr/puGN+CHzx0IKBSpsKlmEmsNV96HKDiP6eu8NSnwdGCEq2mmIHe0JNcg1hqg59hpwtQ7Tiw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/bmp": "^0.10.3", - "@jimp/gif": "^0.10.3", - "@jimp/jpeg": "^0.10.3", - "@jimp/png": "^0.10.3", - "@jimp/tiff": "^0.10.3", - "core-js": "^3.4.1", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/utils": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/utils/-/utils-0.10.3.tgz", - "integrity": "sha512-VcSlQhkil4ReYmg1KkN+WqHyYfZ2XfZxDsKAHSfST1GEz/RQHxKZbX+KhFKtKflnL0F4e6DlNQj3vznMNXCR2w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "core-js": "^3.4.1", - "regenerator-runtime": "^0.13.3" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2055,16 +336,6 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -2087,7 +358,8 @@ "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==" + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", @@ -2152,34 +424,308 @@ "node": ">= 8" } }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.29.tgz", "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "dev": true }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz", @@ -2545,7 +1091,8 @@ "node_modules/@vant/weapp": { "version": "1.11.7", "resolved": "https://registry.npmmirror.com/@vant/weapp/-/weapp-1.11.7.tgz", - "integrity": "sha512-Rwn9BBnb4kHSV4XmvBicwtd42J+amEUfnFDcXJsGNPNX4a9c/DoT6YLsm4X1wB2+sQbdiQsbFBLAvGRBxCkD8g==" + "integrity": "sha512-Rwn9BBnb4kHSV4XmvBicwtd42J+amEUfnFDcXJsGNPNX4a9c/DoT6YLsm4X1wB2+sQbdiQsbFBLAvGRBxCkD8g==", + "dev": true }, "node_modules/@vue/cli-overlay": { "version": "5.0.9", @@ -2808,56 +1355,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/@vue/compiler-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz", - "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.21", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", - "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", - "dev": true, - "dependencies": { - "@vue/compiler-core": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", - "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.7", - "postcss": "^8.4.35", - "source-map-js": "^1.0.2" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", - "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", - "dev": true, - "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/shared": "3.4.21" - } - }, "node_modules/@vue/component-compiler-utils": { "version": "3.3.0", "resolved": "https://registry.npmmirror.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", @@ -2922,133 +1419,19 @@ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", "dev": true }, + "node_modules/@vue/composition-api": { + "version": "1.7.2", + "resolved": "https://registry.npmmirror.com/@vue/composition-api/-/composition-api-1.7.2.tgz", + "integrity": "sha512-M8jm9J/laYrYT02665HkZ5l2fWTK4dcVg3BsDHm/pfz+MjDYwX+9FUaZyGwEyXEDonQYRCo0H7aLgdklcIELjw==", + "peerDependencies": { + "vue": ">= 2.5 < 2.7" + } + }, "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.3.4", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz", - "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", - "dependencies": { - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/reactivity-transform": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", - "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", - "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0" - } - }, - "node_modules/@vue/reactivity-transform/node_modules/@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "dependencies": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "node_modules/@vue/reactivity-transform/node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, - "node_modules/@vue/reactivity/node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, - "node_modules/@vue/runtime-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz", - "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", - "dependencies": { - "@vue/reactivity": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/runtime-core/node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, - "node_modules/@vue/runtime-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", - "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", - "dependencies": { - "@vue/runtime-core": "3.3.4", - "@vue/shared": "3.3.4", - "csstype": "^3.1.1" - } - }, - "node_modules/@vue/runtime-dom/node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, - "node_modules/@vue/server-renderer": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz", - "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", - "dependencies": { - "@vue/compiler-ssr": "3.3.4", - "@vue/shared": "3.3.4" - }, - "peerDependencies": { - "vue": "3.3.4" - } - }, - "node_modules/@vue/server-renderer/node_modules/@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "dependencies": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "node_modules/@vue/server-renderer/node_modules/@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", - "dependencies": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/server-renderer/node_modules/@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", - "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/@vue/server-renderer/node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, - "node_modules/@vue/shared": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.21.tgz", - "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", - "dev": true - }, "node_modules/@vue/vue-loader-v15": { "name": "vue-loader", "version": "15.11.1", @@ -3324,15 +1707,6 @@ "node": ">= 10.0.0" } }, - "node_modules/adm-zip": { - "version": "0.5.16", - "resolved": "https://registry.npmmirror.com/adm-zip/-/adm-zip-0.5.16.tgz", - "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", - "dev": true, - "engines": { - "node": ">=12.0" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", @@ -3439,12 +1813,6 @@ "node": ">=4" } }, - "node_modules/any-base": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", - "dev": true - }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", @@ -3577,6 +1945,15 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", @@ -3597,15 +1974,6 @@ } ] }, - "node_modules/base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/baseline-browser-mapping": { "version": "2.8.4", "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.4.tgz", @@ -3659,12 +2027,6 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "node_modules/bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmmirror.com/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", - "dev": true - }, "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.3.tgz", @@ -3799,15 +2161,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmmirror.com/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3911,15 +2264,6 @@ "node": ">=4" } }, - "node_modules/centra": { - "version": "2.7.0", - "resolved": "https://registry.npmmirror.com/centra/-/centra-2.7.0.tgz", - "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.6" - } - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", @@ -4189,12 +2533,6 @@ "node": ">= 12" } }, - "node_modules/compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmmirror.com/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz", @@ -4246,12 +2584,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true - }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -4295,12 +2627,6 @@ "node": ">= 0.6" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/cookie": { "version": "0.7.1", "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.1.tgz", @@ -4352,17 +2678,6 @@ "node": ">=10.13.0" } }, - "node_modules/core-js": { - "version": "3.45.1", - "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.45.1.tgz", - "integrity": "sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz", @@ -4708,16 +3023,16 @@ "node": ">=8.0.0" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, "node_modules/dayjs": { "version": "1.11.0", "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.0.tgz", "integrity": "sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug==" }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==" + }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmmirror.com/debounce/-/debounce-1.2.1.tgz", @@ -4875,6 +3190,19 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz", @@ -4949,12 +3277,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz", @@ -5107,18 +3429,6 @@ "node": ">=10.13.0" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.4.tgz", @@ -5184,44 +3494,6 @@ "node": ">= 0.4" } }, - "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", @@ -5508,11 +3780,6 @@ "node": ">=4.0" } }, - "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/esutils": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz", @@ -5640,12 +3907,6 @@ "which": "bin/which" } }, - "node_modules/exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmmirror.com/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==", - "dev": true - }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmmirror.com/express/-/express-4.21.2.tgz", @@ -5707,12 +3968,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/exsolve": { - "version": "1.0.7", - "resolved": "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.7.tgz", - "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", - "dev": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5808,15 +4063,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-type": { - "version": "9.0.0", - "resolved": "https://registry.npmmirror.com/file-type/-/file-type-9.0.0.tgz", - "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", @@ -6020,33 +4266,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/generic-names": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/generic-names/-/generic-names-4.0.0.tgz", - "integrity": "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==", - "dev": true, - "dependencies": { - "loader-utils": "^3.2.0" - } - }, - "node_modules/generic-names/node_modules/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "dev": true, - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -6124,6 +4343,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-escape": { + "version": "0.0.2", + "resolved": "https://registry.npmmirror.com/glob-escape/-/glob-escape-0.0.2.tgz", + "integrity": "sha512-L/cXYz8x7qer1HAyUQ+mbjcUsJVdpRxpAf7CwqHoNBs9vTpABlGfNN4tzkDxt+u3Z7ZncVyKlCNPtzb0R/7WbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", @@ -6142,16 +4370,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmmirror.com/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz", @@ -6286,7 +4504,6 @@ "version": "1.2.0", "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, "bin": { "he": "bin/he" } @@ -6538,12 +4755,6 @@ "node": ">=0.10.0" } }, - "node_modules/icss-replace-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", - "dev": true - }, "node_modules/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz", @@ -6585,6 +4796,12 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "dev": true + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz", @@ -6627,17 +4844,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/invert-kv": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/invert-kv/-/invert-kv-3.0.1.tgz", - "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sindresorhus/invert-kv?sponsor=1" - } + "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==", + "dev": true }, "node_modules/ipaddr.js": { "version": "2.2.0", @@ -6723,12 +4934,6 @@ "node": ">=8" } }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", @@ -6831,18 +5036,6 @@ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, - "node_modules/isbinaryfile": { - "version": "5.0.2", - "resolved": "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-5.0.2.tgz", - "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", - "dev": true, - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", @@ -6902,20 +5095,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jimp": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/jimp/-/jimp-0.10.3.tgz", - "integrity": "sha512-meVWmDMtyUG5uYjFkmzu0zBgnCvvxwWNi27c4cg55vWNVC9ES4Lcwb+ogx+uBBQE3Q+dLKjXaLl0JVW+nUNwbQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "@jimp/custom": "^0.10.3", - "@jimp/plugins": "^0.10.3", - "@jimp/types": "^0.10.3", - "core-js": "^3.4.1", - "regenerator-runtime": "^0.13.3" - } - }, "node_modules/joi": { "version": "17.13.3", "resolved": "https://registry.npmmirror.com/joi/-/joi-17.13.3.tgz", @@ -6929,12 +5108,6 @@ "@sideway/pinpoint": "^2.0.0" } }, - "node_modules/jpeg-js": { - "version": "0.3.7", - "resolved": "https://registry.npmmirror.com/jpeg-js/-/jpeg-js-0.3.7.tgz", - "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==", - "dev": true - }, "node_modules/js-message": { "version": "1.0.7", "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz", @@ -6962,18 +5135,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz", @@ -7016,12 +5177,6 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true - }, "node_modules/jsonfile": { "version": "6.2.0", "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz", @@ -7086,18 +5241,6 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, - "node_modules/lcid": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/lcid/-/lcid-3.1.1.tgz", - "integrity": "sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==", - "dev": true, - "dependencies": { - "invert-kv": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", @@ -7111,12 +5254,6 @@ "node": ">= 0.8.0" } }, - "node_modules/licia": { - "version": "1.41.1", - "resolved": "https://registry.npmmirror.com/licia/-/licia-1.41.1.tgz", - "integrity": "sha512-XqObV8u1KEMdYWaNK0leRrTwhzKnLQEkhbnuUu7qGNH3zJoN7l9sfvF6PfHstSCuUOmpEP+0SBjRrk0I9uZs8g==", - "dev": true - }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", @@ -7126,55 +5263,6 @@ "node": ">=10" } }, - "node_modules/lines-and-columns": { - "version": "2.0.4", - "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz", - "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/load-bmfont": { - "version": "1.4.2", - "resolved": "https://registry.npmmirror.com/load-bmfont/-/load-bmfont-1.4.2.tgz", - "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==", - "dev": true, - "dependencies": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^3.7.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" - } - }, - "node_modules/load-bmfont/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-bmfont/node_modules/phin": { - "version": "3.7.1", - "resolved": "https://registry.npmmirror.com/phin/-/phin-3.7.1.tgz", - "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==", - "dev": true, - "dependencies": { - "centra": "^2.7.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz", @@ -7210,49 +5298,6 @@ "json5": "lib/cli.js" } }, - "node_modules/local-pkg": { - "version": "1.1.2", - "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.2.tgz", - "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", - "dev": true, - "dependencies": { - "mlly": "^1.7.4", - "pkg-types": "^2.3.0", - "quansync": "^0.2.11" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/local-pkg/node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "dev": true - }, - "node_modules/local-pkg/node_modules/pkg-types": { - "version": "2.3.0", - "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-2.3.0.tgz", - "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", - "dev": true, - "dependencies": { - "confbox": "^0.2.2", - "exsolve": "^1.0.7", - "pathe": "^2.0.3" - } - }, - "node_modules/localstorage-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/localstorage-polyfill/-/localstorage-polyfill-1.0.1.tgz", - "integrity": "sha512-m4iHVZxFH5734oQcPKU08025gIz2+4bjWR9lulP8ZYxEJR0BpA0w32oJmkzh8y3UI9ci7xCBehQDc3oA1X+VHw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", @@ -7274,12 +5319,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, "node_modules/lodash.defaultsdeep": { "version": "4.6.1", "resolved": "https://registry.npmmirror.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", @@ -7530,14 +5569,6 @@ "yallist": "^3.0.2" } }, - "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -7573,12 +5604,6 @@ "node": ">= 4.0.0" } }, - "node_modules/merge": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz", - "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", - "dev": true - }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -7634,18 +5659,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", @@ -7674,15 +5687,6 @@ "node": ">=6" } }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/mini-css-extract-plugin": { "version": "2.9.4", "resolved": "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", @@ -7801,30 +5805,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mlly": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.8.0.tgz", - "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", - "dev": true, - "dependencies": { - "acorn": "^8.15.0", - "pathe": "^2.0.3", - "pkg-types": "^1.3.1", - "ufo": "^1.6.1" - } - }, "node_modules/module-alias": { "version": "2.2.3", "resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz", @@ -7874,6 +5854,7 @@ "version": "3.3.11", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, "funding": [ { "type": "github", @@ -7924,6 +5905,13 @@ "tslib": "^2.0.3" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz", @@ -8070,12 +6058,6 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, - "node_modules/omggif": { - "version": "1.0.10", - "resolved": "https://registry.npmmirror.com/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", - "dev": true - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", @@ -8257,19 +6239,6 @@ "node": ">=8" } }, - "node_modules/os-locale-s-fix": { - "version": "1.0.8-fix-1", - "resolved": "https://registry.npmmirror.com/os-locale-s-fix/-/os-locale-s-fix-1.0.8-fix-1.tgz", - "integrity": "sha512-Sv0OvhPiMutICiwORAUefv02DCPb62IelBmo8ZsSrRHyI3FStqIWZvjqDkvtjU+lcujo7UNir+dCwKSqlEQ/5w==", - "dev": true, - "dependencies": { - "lcid": "^3.0.0" - }, - "engines": { - "node": ">=10", - "yarn": "^1.22.4" - } - }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/p-finally/-/p-finally-1.0.0.tgz", @@ -8359,34 +6328,6 @@ "node": ">=6" } }, - "node_modules/parse-bmfont-ascii": { - "version": "1.0.6", - "resolved": "https://registry.npmmirror.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", - "dev": true - }, - "node_modules/parse-bmfont-binary": { - "version": "1.0.6", - "resolved": "https://registry.npmmirror.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", - "dev": true - }, - "node_modules/parse-bmfont-xml": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", - "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", - "dev": true, - "dependencies": { - "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.5.0" - } - }, - "node_modules/parse-headers": { - "version": "2.0.6", - "resolved": "https://registry.npmmirror.com/parse-headers/-/parse-headers-2.0.6.tgz", - "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==", - "dev": true - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz", @@ -8499,19 +6440,6 @@ "node": ">=8" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true - }, - "node_modules/phin": { - "version": "2.9.3", - "resolved": "https://registry.npmmirror.com/phin/-/phin-2.9.3.tgz", - "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true - }, "node_modules/picocolors": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.0.tgz", @@ -8530,15 +6458,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pinia": { "version": "2.1.6", "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.6.tgz", @@ -8589,38 +6508,6 @@ } } }, - "node_modules/pixelmatch": { - "version": "4.0.2", - "resolved": "https://registry.npmmirror.com/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", - "dev": true, - "dependencies": { - "pngjs": "^3.0.0" - }, - "bin": { - "pixelmatch": "bin/pixelmatch" - } - }, - "node_modules/pkg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, - "dependencies": { - "confbox": "^0.1.8", - "mlly": "^1.7.4", - "pathe": "^2.0.1" - } - }, - "node_modules/pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/portfinder": { "version": "1.0.38", "resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.38.tgz", @@ -8638,6 +6525,7 @@ "version": "8.5.6", "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -8756,50 +6644,16 @@ "postcss": "^8.2.15" } }, - "node_modules/postcss-import": { - "version": "14.1.0", - "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-14.1.0.tgz", - "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "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==", "dev": true, "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" + "urijs": "^1.18.12" }, "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, - "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" - }, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } + "node": ">=0.12.9" } }, "node_modules/postcss-loader": { @@ -8934,25 +6788,6 @@ "postcss": "^8.2.15" } }, - "node_modules/postcss-modules": { - "version": "4.3.1", - "resolved": "https://registry.npmmirror.com/postcss-modules/-/postcss-modules-4.3.1.tgz", - "integrity": "sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==", - "dev": true, - "dependencies": { - "generic-names": "^4.0.0", - "icss-replace-symbols": "^1.1.0", - "lodash.camelcase": "^4.3.0", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "string-hash": "^1.1.1" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", @@ -9263,6 +7098,18 @@ "postcss": "^8.2.15" } }, + "node_modules/postcss-urlrewrite": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/postcss-urlrewrite/-/postcss-urlrewrite-0.2.2.tgz", + "integrity": "sha512-DxPSgykgHjoV4Z+ygvq2C5HkiuiKQQD74xpoNQSQuyi8zab9nODVtNKfnCN6BEv9VZrjpOGLGAf8BDvgG6EtHg==", + "dev": true, + "dependencies": { + "postcss-helpers": "^0.3.2" + }, + "engines": { + "node": ">=0.12.9" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -9272,7 +7119,8 @@ "node_modules/postcss/node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -9309,15 +7157,6 @@ "renderkid": "^3.0.0" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -9388,21 +7227,6 @@ "node": ">=6" } }, - "node_modules/qrcode-reader": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/qrcode-reader/-/qrcode-reader-1.0.4.tgz", - "integrity": "sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==", - "dev": true - }, - "node_modules/qrcode-terminal": { - "version": "0.12.0", - "resolved": "https://registry.npmmirror.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", - "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", - "dev": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.0.tgz", @@ -9418,22 +7242,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/quansync": { - "version": "0.2.11", - "resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.11.tgz", - "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/antfu" - }, - { - "type": "individual", - "url": "https://github.com/sponsors/sxzz" - } - ] - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9487,15 +7295,6 @@ "node": ">= 0.8" } }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "dependencies": { - "pify": "^2.3.0" - } - }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz", @@ -9624,12 +7423,6 @@ "node": ">=8.10.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz", @@ -9805,11 +7598,93 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "dev": true + "node_modules/sass": { + "version": "1.92.1", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.92.1.tgz", + "integrity": "sha512-ffmsdbwqb3XeyR8jJR6KelIXARM9bFQe8A6Q3W4Klmwy5Ckd5gz7jgUNHo4UOqutU5Sk1DtKLbpDP0nLCg1xqQ==", + "dev": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.5", + "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-16.0.5.tgz", + "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } }, "node_modules/schema-utils": { "version": "3.3.0", @@ -9829,12 +7704,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/scule": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", - "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", - "dev": true - }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz", @@ -10201,6 +8070,7 @@ "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==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -10320,12 +8190,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/string-hash/-/string-hash-1.1.3.tgz", - "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==", - "dev": true - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", @@ -10382,24 +8246,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-3.0.0.tgz", - "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", - "dev": true, - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true - }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.1.tgz", @@ -10664,26 +8510,6 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, - "node_modules/timm": { - "version": "1.7.1", - "resolved": "https://registry.npmmirror.com/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==", - "dev": true - }, - "node_modules/tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -10776,85 +8602,12 @@ "node": ">=14.17" } }, - "node_modules/ufo": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "dev": true - }, "node_modules/undici-types": { "version": "7.12.0", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.12.0.tgz", "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==", "dev": true }, - "node_modules/unimport": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/unimport/-/unimport-4.1.1.tgz", - "integrity": "sha512-j9+fijH6aDd05yv1fXlyt7HSxtOWtGtrZeYTVBsSUg57Iuf+Ps2itIZjeyu7bEQ4k0WOgYhHrdW8m/pJgOpl5g==", - "dev": true, - "dependencies": { - "acorn": "^8.14.0", - "escape-string-regexp": "^5.0.0", - "estree-walker": "^3.0.3", - "fast-glob": "^3.3.3", - "local-pkg": "^1.0.0", - "magic-string": "^0.30.17", - "mlly": "^1.7.4", - "pathe": "^2.0.2", - "picomatch": "^4.0.2", - "pkg-types": "^1.3.1", - "scule": "^1.3.0", - "strip-literal": "^3.0.0", - "unplugin": "^2.1.2", - "unplugin-utils": "^0.2.3" - }, - "engines": { - "node": ">=18.12.0" - } - }, - "node_modules/unimport/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unimport/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/unimport/node_modules/magic-string": { - "version": "0.30.19", - "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz", - "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/unimport/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", @@ -10873,67 +8626,6 @@ "node": ">= 0.8" } }, - "node_modules/unplugin": { - "version": "2.3.10", - "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.10.tgz", - "integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==", - "dev": true, - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "acorn": "^8.15.0", - "picomatch": "^4.0.3", - "webpack-virtual-modules": "^0.6.2" - }, - "engines": { - "node": ">=18.12.0" - } - }, - "node_modules/unplugin-utils": { - "version": "0.2.5", - "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.2.5.tgz", - "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==", - "dev": true, - "dependencies": { - "pathe": "^2.0.3", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/sxzz" - } - }, - "node_modules/unplugin-utils/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/unplugin/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/unplugin/node_modules/webpack-virtual-modules": { - "version": "0.6.2", - "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", - "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", - "dev": true - }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -10979,14 +8671,11 @@ "punycode": "^2.1.0" } }, - "node_modules/utif": { - "version": "2.0.1", - "resolved": "https://registry.npmmirror.com/utif/-/utif-2.0.1.tgz", - "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", - "dev": true, - "dependencies": { - "pako": "^1.0.5" - } + "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==", + "dev": true }, "node_modules/util-deprecate": { "version": "1.0.2", @@ -11038,16 +8727,10 @@ } }, "node_modules/vue": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz", - "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", - "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-sfc": "3.3.4", - "@vue/runtime-dom": "3.3.4", - "@vue/server-renderer": "3.3.4", - "@vue/shared": "3.3.4" - } + "version": "2.6.14", + "resolved": "https://registry.npmmirror.com/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==", + "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details." }, "node_modules/vue-eslint-parser": { "version": "9.4.3", @@ -11184,19 +8867,9 @@ } }, "node_modules/vue-router": { - "version": "4.4.4", - "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.4.4.tgz", - "integrity": "sha512-3MlnDqwRwZwCQVbtVfpsU+nrNymNjnXSsQtXName5925NVC1+326VVfYH9vSrA0N13teGEo8z5x7gbRnGjCDiQ==", - "dev": true, - "dependencies": { - "@vue/devtools-api": "^6.6.4" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "vue": "^3.2.0" - } + "version": "3.6.5", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-3.6.5.tgz", + "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==" }, "node_modules/vue-style-loader": { "version": "4.1.3", @@ -11214,63 +8887,21 @@ "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", "dev": true }, + "node_modules/vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, "node_modules/vue-template-es2015-compiler": { "version": "1.9.1", "resolved": "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "dev": true }, - "node_modules/vue/node_modules/@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "dependencies": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "node_modules/vue/node_modules/@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", - "dependencies": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/vue/node_modules/@vue/compiler-sfc": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", - "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", - "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-ssr": "3.3.4", - "@vue/reactivity-transform": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0", - "postcss": "^8.1.10", - "source-map-js": "^1.0.2" - } - }, - "node_modules/vue/node_modules/@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", - "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "node_modules/vue/node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - }, "node_modules/watchpack": { "version": "2.4.4", "resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.4.tgz", @@ -11876,18 +9507,6 @@ } } }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmmirror.com/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -11897,58 +9516,6 @@ "node": ">=12" } }, - "node_modules/xml-parse-from-string": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", - "dev": true - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xregexp": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/xregexp/-/xregexp-3.1.0.tgz", - "integrity": "sha512-4Y1x6DyB8xRoxosooa6PlGWqmmSKatbzhrftZ7Purmm4B8R4qIEJG1A2hZsdz5DhmIqS0msC0I7KEq93GphEVg==", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", @@ -12025,16 +9592,6 @@ "js-message": "1.0.7" } }, - "@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, "@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.24.7.tgz", @@ -12051,63 +9608,6 @@ "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "dev": true }, - "@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - } - }, - "@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", - "dev": true, - "requires": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "dependencies": { - "@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, - "requires": { - "@babel/types": "^7.28.4" - } - }, - "@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - } - } - } - }, "@babel/helper-compilation-targets": { "version": "7.27.2", "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", @@ -12121,54 +9621,11 @@ "semver": "^6.3.1" } }, - "@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true - }, - "@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "requires": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "dependencies": { - "@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - } - } - } - }, - "@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - } - }, - "@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==" - }, "@babel/helper-validator-identifier": { "version": "7.27.1", "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==" + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.27.1", @@ -12176,28 +9633,6 @@ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true }, - "@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dev": true, - "requires": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "dependencies": { - "@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - } - } - } - }, "@babel/highlight": { "version": "7.25.9", "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.25.9.tgz", @@ -12210,601 +9645,82 @@ "picocolors": "^1.0.0" } }, - "@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", - "requires": { - "@babel/types": "^7.25.6" - } + "@dcloudio/types": { + "version": "3.4.21", + "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.4.21.tgz", + "integrity": "sha512-rsv3XfAaD/dtuVboPeYh+vPcULnWyozGaGKHWyN0dYRm7L1uypFUM30qNYMj9iNmbAENuBjV177S1gNEBIvdDA==", + "peer": true }, - "@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", - "dev": true - }, - "@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - } - }, - "@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, - "requires": { - "@babel/types": "^7.28.4" - } - }, - "@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - } - }, - "picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - } - } - }, - "@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", - "debug": "^4.3.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - } - }, - "@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, - "requires": { - "@babel/types": "^7.28.4" - } - }, - "@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - } - }, - "picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", - "requires": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - } + "@dcloudio/uni-app": { + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app/-/uni-app-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-h9Og8v85U3hOBh5FCbnmmGPzX8OTJssJvQxZzi01J6lbWrqxnuP/DS+8zFb+A2mGgpzzeK/KHv9i4mUsVNv4TA==", + "requires": {} }, "@dcloudio/uni-cli-shared": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-l+PR5c3clanpEgkFzuWkrpH0b74QhSmoe8eJs3RNe8BCb8ttRR7mSt+dndttEXz5aCKG1J/gt75U8oLNshy3VA==", + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-+zHK6mxN+2PcVUk7SJkrY6mXO0pk65ghJgYEoElF3UT4M0TPRe+bc3tFhTn7hGSYxP1JYx8I0RoxkIeTMDK0xA==", "dev": true, "requires": { - "@ampproject/remapping": "^2.1.2", - "@babel/code-frame": "7.24.7", - "@babel/core": "7.25.2", - "@babel/parser": "7.25.6", - "@babel/types": "7.25.6", - "@dcloudio/uni-i18n": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@intlify/core-base": "9.1.9", - "@intlify/shared": "9.1.9", - "@intlify/vue-devtools": "9.1.9", - "@rollup/pluginutils": "5.1.0", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/compiler-ssr": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21", - "adm-zip": "0.5.16", - "autoprefixer": "10.4.20", - "base64url": "^3.0.1", - "chokidar": "3.6.0", - "compare-versions": "^3.6.0", - "debug": "4.3.7", - "entities": "^4.5.0", - "es-module-lexer": "1.5.4", - "esbuild": "0.20.2", - "estree-walker": "2.0.2", - "fast-glob": "3.3.3", - "fs-extra": "10.1.0", - "hash-sum": "2.0.0", - "isbinaryfile": "5.0.2", - "jsonc-parser": "3.3.1", - "lines-and-columns": "^2.0.4", - "magic-string": "0.30.11", - "merge": "2.1.1", - "mime": "3.0.0", - "module-alias": "2.2.3", - "os-locale-s-fix": "^1.0.8-fix-1", - "picocolors": "1.1.0", - "postcss-import": "^14.0.2", - "postcss-load-config": "^3.1.1", - "postcss-modules": "^4.3.0", - "postcss-selector-parser": "6.1.2", - "resolve": "1.22.8", - "source-map-js": "1.2.1", - "tapable": "^2.2.0", - "unimport": "4.1.1", - "unplugin-auto-import": "19.1.0", - "xregexp": "3.1.0" + "escape-string-regexp": "^4.0.0", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.0", + "glob-escape": "^0.0.2", + "hash-sum": "^1.0.2", + "postcss-urlrewrite": "^0.2.2", + "strip-json-comments": "^2.0.1" }, "dependencies": { - "@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "requires": { - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "requires": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "requires": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", - "dev": true, - "requires": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "unplugin-auto-import": { - "version": "19.1.0", - "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-19.1.0.tgz", - "integrity": "sha512-B+TGBEBHqY9aR+7YfShfLujETOHstzpV+yaqgy5PkfV0QG7Py+TYMX7vJ9W4SrysHR+UzR+gzcx/nuZjmPeclA==", - "dev": true, - "requires": { - "local-pkg": "^1.0.0", - "magic-string": "^0.30.17", - "picomatch": "^4.0.2", - "unimport": "^4.1.1", - "unplugin": "^2.2.0", - "unplugin-utils": "^0.2.4" - }, - "dependencies": { - "magic-string": { - "version": "0.30.19", - "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz", - "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - } - } + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", + "dev": true }, - "vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "requires": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" - } + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true } } }, "@dcloudio/uni-h5": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-eiFmQpxCAAVPdeC0gyZuCtNJJtMNoie6T7ao2U8Ucxn1I6uXrpzWyP2nusuqtAzd0JgRgo/6T8xUZjOw2C9OhQ==", + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-hQ1ONQm+8ZKnc6FRbRT9xWGwH4ed0KqVIgvwduG7bVnvcvhxIuFhPUthMCYyvQaVjdp0yjBiUicVEwomWSsZRw==", "dev": true, "requires": { - "@dcloudio/uni-h5-vite": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-h5-vue": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-i18n": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21", - "debug": "4.3.7", - "localstorage-polyfill": "^1.0.1", - "postcss-selector-parser": "6.1.2", - "safe-area-insets": "1.4.1", - "vue-router": "4.4.4", - "xmlhttprequest": "^1.8.0" + "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" }, "dependencies": { - "@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "requires": { - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "requires": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "requires": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", + "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==", "dev": true, "requires": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "requires": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" + "postcss-helpers": "^0.3.3" } } } }, - "@dcloudio/uni-h5-vite": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vite/-/uni-h5-vite-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-jQ1rqXyjUR0j8Lvfbbjtvr5tiqTVXbk04qSzWzI8s36CO9ljNlAsTkd1tPxGlZNLKj6Ag1glwSvqaVzimPHuqw==", - "dev": true, - "requires": { - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@rollup/pluginutils": "5.1.0", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21", - "debug": "4.3.7", - "fs-extra": "10.1.0", - "mime": "3.0.0", - "module-alias": "2.2.3" - }, - "dependencies": { - "@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "requires": { - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "requires": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "requires": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", - "dev": true, - "requires": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "requires": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" - } - } - } - }, - "@dcloudio/uni-h5-vue": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vue/-/uni-h5-vue-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-x16jzybDQAIFtq/uou+t4qyH93WBpC6QGF3CCQ1QF5YzwFtmzw52sFII2cjsjPxgad4+WpdQhQM4eu6a2l3HEw==", - "dev": true, - "requires": { - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/server-renderer": "3.4.21" - }, - "dependencies": { - "@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", - "dev": true, - "peer": true, - "requires": { - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", - "dev": true, - "peer": true, - "requires": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", - "dev": true, - "peer": true, - "requires": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", - "csstype": "^3.1.3" - } - }, - "@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", - "dev": true, - "requires": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "vue": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dev": true, - "peer": true, - "requires": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" - } - } - } - }, - "@dcloudio/uni-i18n": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-i18n/-/uni-i18n-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-7nscVrmAhhBkLkEDOa4+fXceOT7vp1DnPQZfepqeP5enmsA+L3sQpmyl78UG0i4ZHcVGLaqmPrQgWqg3MgmJVQ==", - "dev": true - }, - "@dcloudio/uni-mp-compiler": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-compiler/-/uni-mp-compiler-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-Gua1gqurqWf4TnKTaRbaig4JHiXqt32qyWpwQGanyqLMVVptQcMzs+Gx3pcDmTO/Kk4bEN9sZoT5nR1jMsKvKg==", - "dev": true, - "requires": { - "@babel/generator": "7.25.6", - "@babel/parser": "7.25.6", - "@babel/types": "7.25.6", - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/shared": "3.4.21", - "estree-walker": "2.0.2" - }, - "dependencies": { - "@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", - "dev": true, - "requires": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - } - } - }, - "@dcloudio/uni-mp-vite": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vite/-/uni-mp-vite-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-zfSrLT/+m+j9+Glusyb1LffgdkUhnaQD8MMK8rrDnj/90ZQlngAhYarT0968ISqxKQ0nNHk4DDvlgGmWKD0dHQ==", - "dev": true, - "requires": { - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-i18n": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-compiler": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-vue": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/shared": "3.4.21", - "debug": "4.3.7" - } - }, - "@dcloudio/uni-mp-vue": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vue/-/uni-mp-vue-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-EIFwi0au3oeclW9DKB8zUawNdzyGzyxMvUyzgzcjqoiONcla4fqFfV//89g/vot+50htbsfWOecIiZrNDGiJ5w==", - "dev": true, - "requires": { - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/shared": "3.4.21" - } - }, "@dcloudio/uni-mp-weixin": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-weixin/-/uni-mp-weixin-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-fG5aUUtyV4IrXY1v04GYn3t5RCoYuc4lRTwrXrWwa2r/Bohtb7n0uKiPLtSjLzoz6spXcn4cXdiqg7XJQFLLWw==", - "dev": true, - "requires": { - "@dcloudio/uni-cli-shared": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-vite": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-mp-vue": "3.0.0-alpha-4080120250821001", - "@dcloudio/uni-shared": "3.0.0-alpha-4080120250821001", - "@vue/shared": "3.4.21", - "jimp": "0.10.3", - "licia": "1.41.1", - "qrcode-reader": "1.0.4", - "qrcode-terminal": "0.12.0", - "ws": "8.18.0" - } - }, - "@dcloudio/uni-shared": { - "version": "3.0.0-alpha-4080120250821001", - "resolved": "https://registry.npmmirror.com/@dcloudio/uni-shared/-/uni-shared-3.0.0-alpha-4080120250821001.tgz", - "integrity": "sha512-oIWdjiUezdiXxw83zcc6USX4XC9pWM125JQdXpKpSYOwg7revpyTB1JYYY29X58RJbctyhtMJcMun7A2nj84Qg==", - "dev": true, - "requires": { - "@vue/shared": "3.4.21" - } + "version": "2.0.2-alpha-4080120250905001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-weixin/-/uni-mp-weixin-2.0.2-alpha-4080120250905001.tgz", + "integrity": "sha512-tyEt9RLhG39EBH+sgGPUJmBbJDwMcnv46CLzPChDLDVdunupqjHB42MmzUY8yrDNeZuD4MB02NAI3oLUrsSw0w==", + "dev": true }, "@discoveryjs/json-ext": { "version": "0.5.7", @@ -12812,167 +9728,6 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, - "@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "dev": true, - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "dev": true, - "optional": true - }, "@eslint-community/eslint-utils": { "version": "4.9.0", "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", @@ -13049,456 +9804,6 @@ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, - "@intlify/core-base": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz", - "integrity": "sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==", - "dev": true, - "requires": { - "@intlify/devtools-if": "9.1.9", - "@intlify/message-compiler": "9.1.9", - "@intlify/message-resolver": "9.1.9", - "@intlify/runtime": "9.1.9", - "@intlify/shared": "9.1.9", - "@intlify/vue-devtools": "9.1.9" - } - }, - "@intlify/devtools-if": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz", - "integrity": "sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==", - "dev": true, - "requires": { - "@intlify/shared": "9.1.9" - } - }, - "@intlify/message-compiler": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz", - "integrity": "sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==", - "dev": true, - "requires": { - "@intlify/message-resolver": "9.1.9", - "@intlify/shared": "9.1.9", - "source-map": "0.6.1" - } - }, - "@intlify/message-resolver": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz", - "integrity": "sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==", - "dev": true - }, - "@intlify/runtime": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/runtime/-/runtime-9.1.9.tgz", - "integrity": "sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==", - "dev": true, - "requires": { - "@intlify/message-compiler": "9.1.9", - "@intlify/message-resolver": "9.1.9", - "@intlify/shared": "9.1.9" - } - }, - "@intlify/shared": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.1.9.tgz", - "integrity": "sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==", - "dev": true - }, - "@intlify/vue-devtools": { - "version": "9.1.9", - "resolved": "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz", - "integrity": "sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==", - "dev": true, - "requires": { - "@intlify/message-resolver": "9.1.9", - "@intlify/runtime": "9.1.9", - "@intlify/shared": "9.1.9" - } - }, - "@jimp/bmp": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/bmp/-/bmp-0.10.3.tgz", - "integrity": "sha512-keMOc5woiDmONXsB/6aXLR4Z5Q+v8lFq3EY2rcj2FmstbDMhRuGbmcBxlEgOqfRjwvtf/wOtJ3Of37oAWtVfLg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "bmp-js": "^0.1.0", - "core-js": "^3.4.1" - } - }, - "@jimp/core": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/core/-/core-0.10.3.tgz", - "integrity": "sha512-Gd5IpL3U2bFIO57Fh/OA3HCpWm4uW/pU01E75rI03BXfTdz3T+J7TwvyG1XaqsQ7/DSlS99GXtLQPlfFIe28UA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "any-base": "^1.1.0", - "buffer": "^5.2.0", - "core-js": "^3.4.1", - "exif-parser": "^0.1.12", - "file-type": "^9.0.0", - "load-bmfont": "^1.3.1", - "mkdirp": "^0.5.1", - "phin": "^2.9.1", - "pixelmatch": "^4.0.2", - "tinycolor2": "^1.4.1" - } - }, - "@jimp/custom": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/custom/-/custom-0.10.3.tgz", - "integrity": "sha512-nZmSI+jwTi5IRyNLbKSXQovoeqsw+D0Jn0SxW08wYQvdkiWA8bTlDQFgQ7HVwCAKBm8oKkDB/ZEo9qvHJ+1gAQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/core": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/gif": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/gif/-/gif-0.10.3.tgz", - "integrity": "sha512-vjlRodSfz1CrUvvrnUuD/DsLK1GHB/yDZXHthVdZu23zYJIW7/WrIiD1IgQ5wOMV7NocfrvPn2iqUfBP81/WWA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "omggif": "^1.0.9" - } - }, - "@jimp/jpeg": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/jpeg/-/jpeg-0.10.3.tgz", - "integrity": "sha512-AAANwgUZOt6f6P7LZxY9lyJ9xclqutYJlsxt3JbriXUGJgrrFAIkcKcqv1nObgmQASSAQKYaMV9KdHjMlWFKlQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "jpeg-js": "^0.3.4" - } - }, - "@jimp/plugin-blit": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-blit/-/plugin-blit-0.10.3.tgz", - "integrity": "sha512-5zlKlCfx4JWw9qUVC7GI4DzXyxDWyFvgZLaoGFoT00mlXlN75SarlDwc9iZ/2e2kp4bJWxz3cGgG4G/WXrbg3Q==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-blur": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-blur/-/plugin-blur-0.10.3.tgz", - "integrity": "sha512-cTOK3rjh1Yjh23jSfA6EHCHjsPJDEGLC8K2y9gM7dnTUK1y9NNmkFS23uHpyjgsWFIoH9oRh2SpEs3INjCpZhQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-circle": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-circle/-/plugin-circle-0.10.3.tgz", - "integrity": "sha512-51GAPIVelqAcfuUpaM5JWJ0iWl4vEjNXB7p4P7SX5udugK5bxXUjO6KA2qgWmdpHuCKtoNgkzWU9fNSuYp7tCA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-color": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-color/-/plugin-color-0.10.3.tgz", - "integrity": "sha512-RgeHUElmlTH7vpI4WyQrz6u59spiKfVQbsG/XUzfWGamFSixa24ZDwX/yV/Ts+eNaz7pZeIuv533qmKPvw2ujg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "tinycolor2": "^1.4.1" - } - }, - "@jimp/plugin-contain": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-contain/-/plugin-contain-0.10.3.tgz", - "integrity": "sha512-bYJKW9dqzcB0Ihc6u7jSyKa3juStzbLs2LFr6fu8TzA2WkMS/R8h+ddkiO36+F9ILTWHP0CIA3HFe5OdOGcigw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-cover": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-cover/-/plugin-cover-0.10.3.tgz", - "integrity": "sha512-pOxu0cM0BRPzdV468n4dMocJXoMbTnARDY/EpC3ZW15SpMuc/dr1KhWQHgoQX5kVW1Wt8zgqREAJJCQ5KuPKDA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-crop": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-crop/-/plugin-crop-0.10.3.tgz", - "integrity": "sha512-nB7HgOjjl9PgdHr076xZ3Sr6qHYzeBYBs9qvs3tfEEUeYMNnvzgCCGtUl6eMakazZFCMk3mhKmcB9zQuHFOvkg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-displace": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-displace/-/plugin-displace-0.10.3.tgz", - "integrity": "sha512-8t3fVKCH5IVqI4lewe4lFFjpxxr69SQCz5/tlpDLQZsrNScNJivHdQ09zljTrVTCSgeCqQJIKgH2Q7Sk/pAZ0w==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-dither": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-dither/-/plugin-dither-0.10.3.tgz", - "integrity": "sha512-JCX/oNSnEg1kGQ8ffZ66bEgQOLCY3Rn+lrd6v1jjLy/mn9YVZTMsxLtGCXpiCDC2wG/KTmi4862ysmP9do9dAQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-fisheye": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.10.3.tgz", - "integrity": "sha512-RRZb1wqe+xdocGcFtj2xHU7sF7xmEZmIa6BmrfSchjyA2b32TGPWKnP3qyj7p6LWEsXn+19hRYbjfyzyebPElQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-flip": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-flip/-/plugin-flip-0.10.3.tgz", - "integrity": "sha512-0epbi8XEzp0wmSjoW9IB0iMu0yNF17aZOxLdURCN3Zr+8nWPs5VNIMqSVa1Y62GSyiMDpVpKF/ITiXre+EqrPg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-gaussian": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.10.3.tgz", - "integrity": "sha512-25eHlFbHUDnMMGpgRBBeQ2AMI4wsqCg46sue0KklI+c2BaZ+dGXmJA5uT8RTOrt64/K9Wz5E+2n7eBnny4dfpQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-invert": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-invert/-/plugin-invert-0.10.3.tgz", - "integrity": "sha512-effYSApWY/FbtlzqsKXlTLkgloKUiHBKjkQnqh5RL4oQxh/33j6aX+HFdDyQKtsXb8CMd4xd7wyiD2YYabTa0g==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-mask": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-mask/-/plugin-mask-0.10.3.tgz", - "integrity": "sha512-twrg8q8TIhM9Z6Jcu9/5f+OCAPaECb0eKrrbbIajJqJ3bCUlj5zbfgIhiQIzjPJ6KjpnFPSqHQfHkU1Vvk/nVw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-normalize": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-normalize/-/plugin-normalize-0.10.3.tgz", - "integrity": "sha512-xkb5eZI/mMlbwKkDN79+1/t/+DBo8bBXZUMsT4gkFgMRKNRZ6NQPxlv1d3QpRzlocsl6UMxrHnhgnXdLAcgrXw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-print": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-print/-/plugin-print-0.10.3.tgz", - "integrity": "sha512-wjRiI6yjXsAgMe6kVjizP+RgleUCLkH256dskjoNvJzmzbEfO7xQw9g6M02VET+emnbY0CO83IkrGm2q43VRyg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "load-bmfont": "^1.4.0" - } - }, - "@jimp/plugin-resize": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-resize/-/plugin-resize-0.10.3.tgz", - "integrity": "sha512-rf8YmEB1d7Sg+g4LpqF0Mp+dfXfb6JFJkwlAIWPUOR7lGsPWALavEwTW91c0etEdnp0+JB9AFpy6zqq7Lwkq6w==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-rotate": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-rotate/-/plugin-rotate-0.10.3.tgz", - "integrity": "sha512-YXLlRjm18fkW9MOHUaVAxWjvgZM851ofOipytz5FyKp4KZWDLk+dZK1JNmVmK7MyVmAzZ5jsgSLhIgj+GgN0Eg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-scale": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-scale/-/plugin-scale-0.10.3.tgz", - "integrity": "sha512-5DXD7x7WVcX1gUgnlFXQa8F+Q3ThRYwJm+aesgrYvDOY+xzRoRSdQvhmdd4JEEue3lyX44DvBSgCIHPtGcEPaw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-shadow": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-shadow/-/plugin-shadow-0.10.3.tgz", - "integrity": "sha512-/nkFXpt2zVcdP4ETdkAUL0fSzyrC5ZFxdcphbYBodqD7fXNqChS/Un1eD4xCXWEpW8cnG9dixZgQgStjywH0Mg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugin-threshold": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugin-threshold/-/plugin-threshold-0.10.3.tgz", - "integrity": "sha512-Dzh0Yq2wXP2SOnxcbbiyA4LJ2luwrdf1MghNIt9H+NX7B+IWw/N8qA2GuSm9n4BPGSLluuhdAWJqHcTiREriVA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1" - } - }, - "@jimp/plugins": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/plugins/-/plugins-0.10.3.tgz", - "integrity": "sha512-jTT3/7hOScf0EIKiAXmxwayHhryhc1wWuIe3FrchjDjr9wgIGNN2a7XwCgPl3fML17DXK1x8EzDneCdh261bkw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/plugin-blit": "^0.10.3", - "@jimp/plugin-blur": "^0.10.3", - "@jimp/plugin-circle": "^0.10.3", - "@jimp/plugin-color": "^0.10.3", - "@jimp/plugin-contain": "^0.10.3", - "@jimp/plugin-cover": "^0.10.3", - "@jimp/plugin-crop": "^0.10.3", - "@jimp/plugin-displace": "^0.10.3", - "@jimp/plugin-dither": "^0.10.3", - "@jimp/plugin-fisheye": "^0.10.3", - "@jimp/plugin-flip": "^0.10.3", - "@jimp/plugin-gaussian": "^0.10.3", - "@jimp/plugin-invert": "^0.10.3", - "@jimp/plugin-mask": "^0.10.3", - "@jimp/plugin-normalize": "^0.10.3", - "@jimp/plugin-print": "^0.10.3", - "@jimp/plugin-resize": "^0.10.3", - "@jimp/plugin-rotate": "^0.10.3", - "@jimp/plugin-scale": "^0.10.3", - "@jimp/plugin-shadow": "^0.10.3", - "@jimp/plugin-threshold": "^0.10.3", - "core-js": "^3.4.1", - "timm": "^1.6.1" - } - }, - "@jimp/png": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/png/-/png-0.10.3.tgz", - "integrity": "sha512-YKqk/dkl+nGZxSYIDQrqhmaP8tC3IK8H7dFPnnzFVvbhDnyYunqBZZO3SaZUKTichClRw8k/CjBhbc+hifSGWg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/utils": "^0.10.3", - "core-js": "^3.4.1", - "pngjs": "^3.3.3" - } - }, - "@jimp/tiff": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/tiff/-/tiff-0.10.3.tgz", - "integrity": "sha512-7EsJzZ5Y/EtinkBGuwX3Bi4S+zgbKouxjt9c82VJTRJOQgLWsE/RHqcyRCOQBhHAZ9QexYmDz34medfLKdoX0g==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "core-js": "^3.4.1", - "utif": "^2.0.1" - } - }, - "@jimp/types": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/types/-/types-0.10.3.tgz", - "integrity": "sha512-XGmBakiHZqseSWr/puGN+CHzx0IKBSpsKlmEmsNV96HKDiP6eu8NSnwdGCEq2mmIHe0JNcg1hqg59hpwtQ7Tiw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/bmp": "^0.10.3", - "@jimp/gif": "^0.10.3", - "@jimp/jpeg": "^0.10.3", - "@jimp/png": "^0.10.3", - "@jimp/tiff": "^0.10.3", - "core-js": "^3.4.1", - "timm": "^1.6.1" - } - }, - "@jimp/utils": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/@jimp/utils/-/utils-0.10.3.tgz", - "integrity": "sha512-VcSlQhkil4ReYmg1KkN+WqHyYfZ2XfZxDsKAHSfST1GEz/RQHxKZbX+KhFKtKflnL0F4e6DlNQj3vznMNXCR2w==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "core-js": "^3.4.1", - "regenerator-runtime": "^0.13.3" - } - }, "@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -13509,16 +9814,6 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, - "@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, "@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -13538,7 +9833,8 @@ "@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==" + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.31", @@ -13591,23 +9887,129 @@ "fastq": "^1.6.0" } }, + "@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "optional": true, + "requires": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1", + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + } + }, + "@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "dev": true, + "optional": true + }, + "@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "dev": true, + "optional": true + }, + "@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "dev": true, + "optional": true + }, "@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.29.tgz", "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "dev": true }, - "@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, "@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz", @@ -13950,7 +10352,8 @@ "@vant/weapp": { "version": "1.11.7", "resolved": "https://registry.npmmirror.com/@vant/weapp/-/weapp-1.11.7.tgz", - "integrity": "sha512-Rwn9BBnb4kHSV4XmvBicwtd42J+amEUfnFDcXJsGNPNX4a9c/DoT6YLsm4X1wB2+sQbdiQsbFBLAvGRBxCkD8g==" + "integrity": "sha512-Rwn9BBnb4kHSV4XmvBicwtd42J+amEUfnFDcXJsGNPNX4a9c/DoT6YLsm4X1wB2+sQbdiQsbFBLAvGRBxCkD8g==", + "dev": true }, "@vue/cli-overlay": { "version": "5.0.9", @@ -14143,56 +10546,6 @@ } } }, - "@vue/compiler-core": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz", - "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", - "dev": true, - "requires": { - "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.21", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "@vue/compiler-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", - "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", - "dev": true, - "requires": { - "@vue/compiler-core": "3.4.21", - "@vue/shared": "3.4.21" - } - }, - "@vue/compiler-sfc": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", - "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.7", - "postcss": "^8.4.35", - "source-map-js": "^1.0.2" - } - }, - "@vue/compiler-ssr": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", - "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", - "dev": true, - "requires": { - "@vue/compiler-dom": "3.4.21", - "@vue/shared": "3.4.21" - } - }, "@vue/component-compiler-utils": { "version": "3.3.0", "resolved": "https://registry.npmmirror.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", @@ -14250,140 +10603,17 @@ } } }, + "@vue/composition-api": { + "version": "1.7.2", + "resolved": "https://registry.npmmirror.com/@vue/composition-api/-/composition-api-1.7.2.tgz", + "integrity": "sha512-M8jm9J/laYrYT02665HkZ5l2fWTK4dcVg3BsDHm/pfz+MjDYwX+9FUaZyGwEyXEDonQYRCo0H7aLgdklcIELjw==", + "requires": {} + }, "@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==" }, - "@vue/reactivity": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz", - "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", - "requires": { - "@vue/shared": "3.3.4" - }, - "dependencies": { - "@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - } - } - }, - "@vue/reactivity-transform": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", - "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", - "requires": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0" - }, - "dependencies": { - "@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "requires": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - } - } - }, - "@vue/runtime-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz", - "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", - "requires": { - "@vue/reactivity": "3.3.4", - "@vue/shared": "3.3.4" - }, - "dependencies": { - "@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - } - } - }, - "@vue/runtime-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", - "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", - "requires": { - "@vue/runtime-core": "3.3.4", - "@vue/shared": "3.3.4", - "csstype": "^3.1.1" - }, - "dependencies": { - "@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - } - } - }, - "@vue/server-renderer": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz", - "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", - "requires": { - "@vue/compiler-ssr": "3.3.4", - "@vue/shared": "3.3.4" - }, - "dependencies": { - "@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "requires": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", - "requires": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", - "requires": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - } - } - }, - "@vue/shared": { - "version": "3.4.21", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.21.tgz", - "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", - "dev": true - }, "@vue/vue-loader-v15": { "version": "npm:vue-loader@15.11.1", "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz", @@ -14622,12 +10852,6 @@ "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", "dev": true }, - "adm-zip": { - "version": "0.5.16", - "resolved": "https://registry.npmmirror.com/adm-zip/-/adm-zip-0.5.16.tgz", - "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", - "dev": true - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", @@ -14703,12 +10927,6 @@ "color-convert": "^1.9.0" } }, - "any-base": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", - "dev": true - }, "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", @@ -14795,18 +11013,18 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "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==", + "dev": true + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, - "base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", - "dev": true - }, "baseline-browser-mapping": { "version": "2.8.4", "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.4.tgz", @@ -14848,12 +11066,6 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmmirror.com/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", - "dev": true - }, "body-parser": { "version": "1.20.3", "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.3.tgz", @@ -14949,12 +11161,6 @@ "ieee754": "^1.1.13" } }, - "buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmmirror.com/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", - "dev": true - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", @@ -15026,15 +11232,6 @@ "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", "dev": true }, - "centra": { - "version": "2.7.0", - "resolved": "https://registry.npmmirror.com/centra/-/centra-2.7.0.tgz", - "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", - "dev": true, - "requires": { - "follow-redirects": "^1.15.6" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", @@ -15237,12 +11434,6 @@ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmmirror.com/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz", @@ -15290,12 +11481,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true - }, "connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -15326,12 +11511,6 @@ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "cookie": { "version": "0.7.1", "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.1.tgz", @@ -15369,12 +11548,6 @@ } } }, - "core-js": { - "version": "3.45.1", - "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.45.1.tgz", - "integrity": "sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==", - "dev": true - }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz", @@ -15599,16 +11772,16 @@ "css-tree": "^1.1.2" } }, - "csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, "dayjs": { "version": "1.11.0", "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.0.tgz", "integrity": "sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug==" }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==" + }, "debounce": { "version": "1.2.1", "resolved": "https://registry.npmmirror.com/debounce/-/debounce-1.2.1.tgz", @@ -15717,6 +11890,13 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true + }, "detect-node": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz", @@ -15778,12 +11958,6 @@ } } }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, "domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz", @@ -15903,12 +12077,6 @@ "tapable": "^2.2.0" } }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true - }, "error-ex": { "version": "1.3.4", "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.4.tgz", @@ -15962,37 +12130,6 @@ "hasown": "^2.0.2" } }, - "esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "requires": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, "escalade": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", @@ -16198,11 +12335,6 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, - "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==" - }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz", @@ -16299,12 +12431,6 @@ } } }, - "exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmmirror.com/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==", - "dev": true - }, "express": { "version": "4.21.2", "resolved": "https://registry.npmmirror.com/express/-/express-4.21.2.tgz", @@ -16361,12 +12487,6 @@ } } }, - "exsolve": { - "version": "1.0.7", - "resolved": "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.7.tgz", - "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -16440,12 +12560,6 @@ "flat-cache": "^3.0.4" } }, - "file-type": { - "version": "9.0.0", - "resolved": "https://registry.npmmirror.com/file-type/-/file-type-9.0.0.tgz", - "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==", - "dev": true - }, "fill-range": { "version": "7.1.1", "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", @@ -16590,29 +12704,6 @@ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, - "generic-names": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/generic-names/-/generic-names-4.0.0.tgz", - "integrity": "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==", - "dev": true, - "requires": { - "loader-utils": "^3.2.0" - }, - "dependencies": { - "loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", - "dev": true - } - } - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -16668,6 +12759,12 @@ "path-is-absolute": "^1.0.0" } }, + "glob-escape": { + "version": "0.0.2", + "resolved": "https://registry.npmmirror.com/glob-escape/-/glob-escape-0.0.2.tgz", + "integrity": "sha512-L/cXYz8x7qer1HAyUQ+mbjcUsJVdpRxpAf7CwqHoNBs9vTpABlGfNN4tzkDxt+u3Z7ZncVyKlCNPtzb0R/7WbA==", + "dev": true + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", @@ -16683,16 +12780,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmmirror.com/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "globals": { "version": "13.24.0", "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz", @@ -16784,8 +12871,7 @@ "he": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "highlight.js": { "version": "10.7.3", @@ -16967,12 +13053,6 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "icss-replace-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", - "dev": true - }, "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz", @@ -16992,6 +13072,12 @@ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true }, + "immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "dev": true + }, "import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz", @@ -17024,10 +13110,10 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "invert-kv": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/invert-kv/-/invert-kv-3.0.1.tgz", - "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", + "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==", "dev": true }, "ipaddr.js": { @@ -17087,12 +13173,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", @@ -17162,12 +13242,6 @@ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, - "isbinaryfile": { - "version": "5.0.2", - "resolved": "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-5.0.2.tgz", - "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", - "dev": true - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", @@ -17214,20 +13288,6 @@ } } }, - "jimp": { - "version": "0.10.3", - "resolved": "https://registry.npmmirror.com/jimp/-/jimp-0.10.3.tgz", - "integrity": "sha512-meVWmDMtyUG5uYjFkmzu0zBgnCvvxwWNi27c4cg55vWNVC9ES4Lcwb+ogx+uBBQE3Q+dLKjXaLl0JVW+nUNwbQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "@jimp/custom": "^0.10.3", - "@jimp/plugins": "^0.10.3", - "@jimp/types": "^0.10.3", - "core-js": "^3.4.1", - "regenerator-runtime": "^0.13.3" - } - }, "joi": { "version": "17.13.3", "resolved": "https://registry.npmmirror.com/joi/-/joi-17.13.3.tgz", @@ -17241,12 +13301,6 @@ "@sideway/pinpoint": "^2.0.0" } }, - "jpeg-js": { - "version": "0.3.7", - "resolved": "https://registry.npmmirror.com/jpeg-js/-/jpeg-js-0.3.7.tgz", - "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==", - "dev": true - }, "js-message": { "version": "1.0.7", "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz", @@ -17268,12 +13322,6 @@ "argparse": "^2.0.1" } }, - "jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true - }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz", @@ -17310,12 +13358,6 @@ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, - "jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true - }, "jsonfile": { "version": "6.2.0", "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz", @@ -17374,15 +13416,6 @@ "launch-editor": "^2.11.1" } }, - "lcid": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/lcid/-/lcid-3.1.1.tgz", - "integrity": "sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==", - "dev": true, - "requires": { - "invert-kv": "^3.0.0" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", @@ -17393,57 +13426,12 @@ "type-check": "~0.4.0" } }, - "licia": { - "version": "1.41.1", - "resolved": "https://registry.npmmirror.com/licia/-/licia-1.41.1.tgz", - "integrity": "sha512-XqObV8u1KEMdYWaNK0leRrTwhzKnLQEkhbnuUu7qGNH3zJoN7l9sfvF6PfHstSCuUOmpEP+0SBjRrk0I9uZs8g==", - "dev": true - }, "lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true }, - "lines-and-columns": { - "version": "2.0.4", - "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz", - "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", - "dev": true - }, - "load-bmfont": { - "version": "1.4.2", - "resolved": "https://registry.npmmirror.com/load-bmfont/-/load-bmfont-1.4.2.tgz", - "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==", - "dev": true, - "requires": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^3.7.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "phin": { - "version": "3.7.1", - "resolved": "https://registry.npmmirror.com/phin/-/phin-3.7.1.tgz", - "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==", - "dev": true, - "requires": { - "centra": "^2.7.0" - } - } - } - }, "loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz", @@ -17472,42 +13460,6 @@ } } }, - "local-pkg": { - "version": "1.1.2", - "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.2.tgz", - "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", - "dev": true, - "requires": { - "mlly": "^1.7.4", - "pkg-types": "^2.3.0", - "quansync": "^0.2.11" - }, - "dependencies": { - "confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "dev": true - }, - "pkg-types": { - "version": "2.3.0", - "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-2.3.0.tgz", - "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", - "dev": true, - "requires": { - "confbox": "^0.2.2", - "exsolve": "^1.0.7", - "pathe": "^2.0.3" - } - } - } - }, - "localstorage-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/localstorage-polyfill/-/localstorage-polyfill-1.0.1.tgz", - "integrity": "sha512-m4iHVZxFH5734oQcPKU08025gIz2+4bjWR9lulP8ZYxEJR0BpA0w32oJmkzh8y3UI9ci7xCBehQDc3oA1X+VHw==", - "dev": true - }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", @@ -17523,12 +13475,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, "lodash.defaultsdeep": { "version": "4.6.1", "resolved": "https://registry.npmmirror.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", @@ -17726,14 +13672,6 @@ "yallist": "^3.0.2" } }, - "magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, "math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -17760,12 +13698,6 @@ "fs-monkey": "^1.0.4" } }, - "merge": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz", - "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", - "dev": true - }, "merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -17809,12 +13741,6 @@ "picomatch": "^2.3.1" } }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true - }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", @@ -17834,15 +13760,6 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, "mini-css-extract-plugin": { "version": "2.9.4", "resolved": "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", @@ -17932,27 +13849,6 @@ } } }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mlly": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.8.0.tgz", - "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", - "dev": true, - "requires": { - "acorn": "^8.15.0", - "pathe": "^2.0.3", - "pkg-types": "^1.3.1", - "ufo": "^1.6.1" - } - }, "module-alias": { "version": "2.2.3", "resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz", @@ -17995,7 +13891,8 @@ "nanoid": { "version": "3.3.11", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==" + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true }, "natural-compare": { "version": "1.4.0", @@ -18031,6 +13928,13 @@ "tslib": "^2.0.3" } }, + "node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, "node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz", @@ -18134,12 +14038,6 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, - "omggif": { - "version": "1.0.10", - "resolved": "https://registry.npmmirror.com/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", - "dev": true - }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", @@ -18272,15 +14170,6 @@ } } }, - "os-locale-s-fix": { - "version": "1.0.8-fix-1", - "resolved": "https://registry.npmmirror.com/os-locale-s-fix/-/os-locale-s-fix-1.0.8-fix-1.tgz", - "integrity": "sha512-Sv0OvhPiMutICiwORAUefv02DCPb62IelBmo8ZsSrRHyI3FStqIWZvjqDkvtjU+lcujo7UNir+dCwKSqlEQ/5w==", - "dev": true, - "requires": { - "lcid": "^3.0.0" - } - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/p-finally/-/p-finally-1.0.0.tgz", @@ -18346,34 +14235,6 @@ "callsites": "^3.0.0" } }, - "parse-bmfont-ascii": { - "version": "1.0.6", - "resolved": "https://registry.npmmirror.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", - "dev": true - }, - "parse-bmfont-binary": { - "version": "1.0.6", - "resolved": "https://registry.npmmirror.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", - "dev": true - }, - "parse-bmfont-xml": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", - "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", - "dev": true, - "requires": { - "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.5.0" - } - }, - "parse-headers": { - "version": "2.0.6", - "resolved": "https://registry.npmmirror.com/parse-headers/-/parse-headers-2.0.6.tgz", - "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==", - "dev": true - }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz", @@ -18469,18 +14330,6 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true - }, - "phin": { - "version": "2.9.3", - "resolved": "https://registry.npmmirror.com/phin/-/phin-2.9.3.tgz", - "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", - "dev": true - }, "picocolors": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.0.tgz", @@ -18493,12 +14342,6 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, "pinia": { "version": "2.1.6", "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.6.tgz", @@ -18516,32 +14359,6 @@ } } }, - "pixelmatch": { - "version": "4.0.2", - "resolved": "https://registry.npmmirror.com/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", - "dev": true, - "requires": { - "pngjs": "^3.0.0" - } - }, - "pkg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, - "requires": { - "confbox": "^0.1.8", - "mlly": "^1.7.4", - "pathe": "^2.0.1" - } - }, - "pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "dev": true - }, "portfinder": { "version": "1.0.38", "resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.38.tgz", @@ -18556,6 +14373,7 @@ "version": "8.5.6", "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, "requires": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -18565,7 +14383,8 @@ "picocolors": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true } } }, @@ -18629,25 +14448,13 @@ "dev": true, "requires": {} }, - "postcss-import": { - "version": "14.1.0", - "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-14.1.0.tgz", - "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "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==", "dev": true, "requires": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, - "requires": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" + "urijs": "^1.18.12" } }, "postcss-loader": { @@ -18731,22 +14538,6 @@ "postcss-selector-parser": "^6.0.5" } }, - "postcss-modules": { - "version": "4.3.1", - "resolved": "https://registry.npmmirror.com/postcss-modules/-/postcss-modules-4.3.1.tgz", - "integrity": "sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==", - "dev": true, - "requires": { - "generic-names": "^4.0.0", - "icss-replace-symbols": "^1.1.0", - "lodash.camelcase": "^4.3.0", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "string-hash": "^1.1.1" - } - }, "postcss-modules-extract-imports": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", @@ -18946,6 +14737,15 @@ "postcss-selector-parser": "^6.0.5" } }, + "postcss-urlrewrite": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/postcss-urlrewrite/-/postcss-urlrewrite-0.2.2.tgz", + "integrity": "sha512-DxPSgykgHjoV4Z+ygvq2C5HkiuiKQQD74xpoNQSQuyi8zab9nODVtNKfnCN6BEv9VZrjpOGLGAf8BDvgG6EtHg==", + "dev": true, + "requires": { + "postcss-helpers": "^0.3.2" + } + }, "postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -18975,12 +14775,6 @@ "renderkid": "^3.0.0" } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -19038,18 +14832,6 @@ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, - "qrcode-reader": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/qrcode-reader/-/qrcode-reader-1.0.4.tgz", - "integrity": "sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==", - "dev": true - }, - "qrcode-terminal": { - "version": "0.12.0", - "resolved": "https://registry.npmmirror.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", - "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", - "dev": true - }, "qs": { "version": "6.13.0", "resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.0.tgz", @@ -19059,12 +14841,6 @@ "side-channel": "^1.0.6" } }, - "quansync": { - "version": "0.2.11", - "resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.11.tgz", - "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", - "dev": true - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -19098,15 +14874,6 @@ "unpipe": "1.0.0" } }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "requires": { - "pify": "^2.3.0" - } - }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz", @@ -19203,12 +14970,6 @@ "picomatch": "^2.2.1" } }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz", @@ -19321,11 +15082,43 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sax": { - "version": "1.4.1", - "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "dev": true + "sass": { + "version": "1.92.1", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.92.1.tgz", + "integrity": "sha512-ffmsdbwqb3XeyR8jJR6KelIXARM9bFQe8A6Q3W4Klmwy5Ckd5gz7jgUNHo4UOqutU5Sk1DtKLbpDP0nLCg1xqQ==", + "dev": true, + "requires": { + "@parcel/watcher": "^2.4.1", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "dependencies": { + "chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "requires": { + "readdirp": "^4.0.1" + } + }, + "readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true + } + } + }, + "sass-loader": { + "version": "16.0.5", + "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-16.0.5.tgz", + "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "dev": true, + "requires": { + "neo-async": "^2.6.2" + } }, "schema-utils": { "version": "3.3.0", @@ -19338,12 +15131,6 @@ "ajv-keywords": "^3.5.2" } }, - "scule": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", - "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", - "dev": true - }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz", @@ -19634,7 +15421,8 @@ "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==" + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true }, "source-map-support": { "version": "0.5.21", @@ -19741,12 +15529,6 @@ "safe-buffer": "~5.2.0" } }, - "string-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/string-hash/-/string-hash-1.1.3.tgz", - "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==", - "dev": true - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", @@ -19785,23 +15567,6 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, - "strip-literal": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-3.0.0.tgz", - "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", - "dev": true, - "requires": { - "js-tokens": "^9.0.1" - }, - "dependencies": { - "js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true - } - } - }, "stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.1.tgz", @@ -19986,23 +15751,6 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, - "timm": { - "version": "1.7.1", - "resolved": "https://registry.npmmirror.com/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==", - "dev": true - }, - "tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -20067,72 +15815,12 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "devOptional": true }, - "ufo": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "dev": true - }, "undici-types": { "version": "7.12.0", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.12.0.tgz", "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==", "dev": true }, - "unimport": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/unimport/-/unimport-4.1.1.tgz", - "integrity": "sha512-j9+fijH6aDd05yv1fXlyt7HSxtOWtGtrZeYTVBsSUg57Iuf+Ps2itIZjeyu7bEQ4k0WOgYhHrdW8m/pJgOpl5g==", - "dev": true, - "requires": { - "acorn": "^8.14.0", - "escape-string-regexp": "^5.0.0", - "estree-walker": "^3.0.3", - "fast-glob": "^3.3.3", - "local-pkg": "^1.0.0", - "magic-string": "^0.30.17", - "mlly": "^1.7.4", - "pathe": "^2.0.2", - "picomatch": "^4.0.2", - "pkg-types": "^1.3.1", - "scule": "^1.3.0", - "strip-literal": "^3.0.0", - "unplugin": "^2.1.2", - "unplugin-utils": "^0.2.3" - }, - "dependencies": { - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0" - } - }, - "magic-string": { - "version": "0.30.19", - "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz", - "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true - } - } - }, "universalify": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", @@ -20145,50 +15833,6 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, - "unplugin": { - "version": "2.3.10", - "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.10.tgz", - "integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==", - "dev": true, - "requires": { - "@jridgewell/remapping": "^2.3.5", - "acorn": "^8.15.0", - "picomatch": "^4.0.3", - "webpack-virtual-modules": "^0.6.2" - }, - "dependencies": { - "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true - }, - "webpack-virtual-modules": { - "version": "0.6.2", - "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", - "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", - "dev": true - } - } - }, - "unplugin-utils": { - "version": "0.2.5", - "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.2.5.tgz", - "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==", - "dev": true, - "requires": { - "pathe": "^2.0.3", - "picomatch": "^4.0.3" - }, - "dependencies": { - "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true - } - } - }, "update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -20216,14 +15860,11 @@ "punycode": "^2.1.0" } }, - "utif": { - "version": "2.0.1", - "resolved": "https://registry.npmmirror.com/utif/-/utif-2.0.1.tgz", - "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", - "dev": true, - "requires": { - "pako": "^1.0.5" - } + "urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmmirror.com/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", + "dev": true }, "util-deprecate": { "version": "1.0.2", @@ -20266,69 +15907,9 @@ "dev": true }, "vue": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz", - "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", - "requires": { - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-sfc": "3.3.4", - "@vue/runtime-dom": "3.3.4", - "@vue/server-renderer": "3.3.4", - "@vue/shared": "3.3.4" - }, - "dependencies": { - "@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", - "requires": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" - } - }, - "@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", - "requires": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/compiler-sfc": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", - "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", - "requires": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-ssr": "3.3.4", - "@vue/reactivity-transform": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0", - "postcss": "^8.1.10", - "source-map-js": "^1.0.2" - } - }, - "@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", - "requires": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" - } - }, - "@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" - } - } + "version": "2.6.14", + "resolved": "https://registry.npmmirror.com/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==" }, "vue-eslint-parser": { "version": "9.4.3", @@ -20422,13 +16003,9 @@ } }, "vue-router": { - "version": "4.4.4", - "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.4.4.tgz", - "integrity": "sha512-3MlnDqwRwZwCQVbtVfpsU+nrNymNjnXSsQtXName5925NVC1+326VVfYH9vSrA0N13teGEo8z5x7gbRnGjCDiQ==", - "dev": true, - "requires": { - "@vue/devtools-api": "^6.6.4" - } + "version": "3.6.5", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-3.6.5.tgz", + "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==" }, "vue-style-loader": { "version": "4.1.3", @@ -20448,6 +16025,15 @@ } } }, + "vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, "vue-template-es2015-compiler": { "version": "1.9.1", "resolved": "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", @@ -20889,64 +16475,12 @@ "dev": true, "requires": {} }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmmirror.com/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, "xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true }, - "xml-parse-from-string": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", - "dev": true - }, - "xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dev": true, - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true - }, - "xregexp": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/xregexp/-/xregexp-3.1.0.tgz", - "integrity": "sha512-4Y1x6DyB8xRoxosooa6PlGWqmmSKatbzhrftZ7Purmm4B8R4qIEJG1A2hZsdz5DhmIqS0msC0I7KEq93GphEVg==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", diff --git a/mini_program/farm-monitor-dashboard/package.json b/mini_program/farm-monitor-dashboard/package.json index 8a2a27f..ec0c9fc 100644 --- a/mini_program/farm-monitor-dashboard/package.json +++ b/mini_program/farm-monitor-dashboard/package.json @@ -10,24 +10,30 @@ "build:h5": "vue-cli-service build --mode production" }, "dependencies": { - "@vant/weapp": "^1.11.6", + "@dcloudio/uni-app": "^2.0.2-alpha-4080120250905001", + "@vue/composition-api": "^1.4.0", "axios": "^0.27.2", "dayjs": "^1.11.0", "pinia": "^2.1.6", - "vue": "^3.3.4" + "vue": "^2.6.14", + "vue-router": "^3.6.5", + "vue-template-compiler": "^2.6.14" }, "devDependencies": { - "@dcloudio/uni-cli-shared": "^3.0.0-alpha-4070620250731002", - "@dcloudio/uni-h5": "^3.0.0-alpha-4070620250731002", - "@dcloudio/uni-mp-weixin": "^3.0.0-alpha-4070620250731002", + "@dcloudio/uni-cli-shared": "^2.0.2-alpha-4080120250905001", + "@dcloudio/uni-h5": "^2.0.2-alpha-4080120250905001", + "@dcloudio/uni-mp-weixin": "^2.0.2-alpha-4080120250905001", + "@vant/weapp": "^1.11.7", "@vue/cli-service": "^5.0.8", "cross-env": "^7.0.3", "eslint": "^8.45.0", "eslint-plugin-vue": "^9.15.0", + "sass": "^1.92.1", + "sass-loader": "^16.0.5", "typescript": "^5.1.0" }, "engines": { "node": "16.20.2", "npm": ">=8.0.0" } -} \ No newline at end of file +} diff --git a/mini_program/farm-monitor-dashboard/public/favicon.svg b/mini_program/farm-monitor-dashboard/public/favicon.svg new file mode 100644 index 0000000..131e31d --- /dev/null +++ b/mini_program/farm-monitor-dashboard/public/favicon.svg @@ -0,0 +1,4 @@ + + + 🐄 + diff --git a/mini_program/farm-monitor-dashboard/public/index.html b/mini_program/farm-monitor-dashboard/public/index.html new file mode 100644 index 0000000..1187abb --- /dev/null +++ b/mini_program/farm-monitor-dashboard/public/index.html @@ -0,0 +1,18 @@ + + + + + + + + + 智慧养殖管理系统 + + + +
+ + + diff --git a/mini_program/farm-monitor-dashboard/src/App.vue b/mini_program/farm-monitor-dashboard/src/App.vue index 7cd7f48..52e6d5e 100644 --- a/mini_program/farm-monitor-dashboard/src/App.vue +++ b/mini_program/farm-monitor-dashboard/src/App.vue @@ -1,75 +1,52 @@ - diff --git a/mini_program/farm-monitor-dashboard/src/components/EarTag.vue b/mini_program/farm-monitor-dashboard/src/components/EarTag.vue new file mode 100644 index 0000000..933f45b --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/EarTag.vue @@ -0,0 +1,1415 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/Home.vue b/mini_program/farm-monitor-dashboard/src/components/Home.vue new file mode 100644 index 0000000..621e284 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/Home.vue @@ -0,0 +1,594 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/Login.vue b/mini_program/farm-monitor-dashboard/src/components/Login.vue new file mode 100644 index 0000000..216db52 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/Login.vue @@ -0,0 +1,553 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/PasswordLogin.vue b/mini_program/farm-monitor-dashboard/src/components/PasswordLogin.vue new file mode 100644 index 0000000..ba0e3cf --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/PasswordLogin.vue @@ -0,0 +1,756 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/Production.vue b/mini_program/farm-monitor-dashboard/src/components/Production.vue new file mode 100644 index 0000000..4c861be --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/Production.vue @@ -0,0 +1,377 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/Profile.vue b/mini_program/farm-monitor-dashboard/src/components/Profile.vue new file mode 100644 index 0000000..e51eb2f --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/Profile.vue @@ -0,0 +1,385 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/Register.vue b/mini_program/farm-monitor-dashboard/src/components/Register.vue new file mode 100644 index 0000000..723fdac --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/Register.vue @@ -0,0 +1,630 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/SmartAnkle.vue b/mini_program/farm-monitor-dashboard/src/components/SmartAnkle.vue new file mode 100644 index 0000000..c3c4d90 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/SmartAnkle.vue @@ -0,0 +1,547 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/SmartCollar.vue b/mini_program/farm-monitor-dashboard/src/components/SmartCollar.vue new file mode 100644 index 0000000..da7679f --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/SmartCollar.vue @@ -0,0 +1,1374 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/SmartHost.vue b/mini_program/farm-monitor-dashboard/src/components/SmartHost.vue new file mode 100644 index 0000000..a35e12a --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/SmartHost.vue @@ -0,0 +1,553 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/components/SmsLogin.vue b/mini_program/farm-monitor-dashboard/src/components/SmsLogin.vue new file mode 100644 index 0000000..8fb0a14 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/components/SmsLogin.vue @@ -0,0 +1,618 @@ + + + + + diff --git a/mini_program/farm-monitor-dashboard/src/main.js b/mini_program/farm-monitor-dashboard/src/main.js index eea556b..4fdce48 100644 --- a/mini_program/farm-monitor-dashboard/src/main.js +++ b/mini_program/farm-monitor-dashboard/src/main.js @@ -1,38 +1,24 @@ -import { createSSRApp } from 'vue' +import Vue from 'vue' import { createPinia } from 'pinia' import App from './App.vue' - -// 引入Vant组件(按需引入) -import Vant from '@vant/weapp' +import VueCompositionAPI from '@vue/composition-api' +import router from './router' // 引入全局样式 import './app.scss' -export function createApp() { - const app = createSSRApp(App) - const pinia = createPinia() - - // 使用Pinia - app.use(pinia) - - // 使用Vant组件 - app.use(Vant) - - // 设置全局属性 - app.config.globalProperties.$uni = uni - app.config.globalProperties.$wx = wx - - return { - app, - pinia - } -} +// 安装composition-api插件 +Vue.use(VueCompositionAPI) // 创建应用实例 -const { app, pinia } = createApp() +const app = new Vue({ + pinia: createPinia(), + router, + render: h => h(App) +}) // 挂载应用 -app.mount('#app') +app.$mount('#app') // 导出应用实例 export default app \ No newline at end of file diff --git a/mini_program/farm-monitor-dashboard/src/router/index.js b/mini_program/farm-monitor-dashboard/src/router/index.js new file mode 100644 index 0000000..c31e98c --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/router/index.js @@ -0,0 +1,127 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' +import Home from '@/components/Home.vue' +import Production from '@/components/Production.vue' +import Profile from '@/components/Profile.vue' +import EarTag from '@/components/EarTag.vue' +import SmartCollar from '@/components/SmartCollar.vue' +import SmartAnkle from '@/components/SmartAnkle.vue' +import SmartHost from '@/components/SmartHost.vue' +import AuthTest from '@/components/AuthTest.vue' +import Login from '@/components/Login.vue' +import SmsLogin from '@/components/SmsLogin.vue' +import Register from '@/components/Register.vue' +import PasswordLogin from '@/components/PasswordLogin.vue' + +Vue.use(VueRouter) + +const routes = [ + { + path: '/', + name: 'Home', + component: Home + }, + { + path: '/login', + name: 'Login', + component: Login + }, + { + path: '/sms-login', + name: 'SmsLogin', + component: SmsLogin + }, + { + path: '/register', + name: 'Register', + component: Register + }, + { + path: '/password-login', + name: 'PasswordLogin', + component: PasswordLogin + }, + { + path: '/production', + name: 'Production', + component: Production + }, + { + path: '/profile', + name: 'Profile', + component: Profile + }, + { + path: '/ear-tag', + name: 'EarTag', + component: EarTag + }, + { + path: '/smart-collar', + name: 'SmartCollar', + component: SmartCollar + }, + { + path: '/smart-ankle', + name: 'SmartAnkle', + component: SmartAnkle + }, + { + path: '/smart-host', + name: 'SmartHost', + component: SmartHost + }, + { + path: '/auth-test', + name: 'AuthTest', + component: AuthTest + } +] + +const router = new VueRouter({ + mode: 'history', + base: process.env.BASE_URL, + routes +}) + +// 路由守卫 +router.beforeEach((to, from, next) => { + // 导入认证工具 + const auth = require('@/utils/auth').default + + // 检查是否需要登录 + const requiresAuth = !['/login', '/sms-login', '/register', '/password-login'].includes(to.path) + const isLoginPage = ['/login', '/sms-login', '/register', '/password-login'].includes(to.path) + const isAuthenticated = auth.isAuthenticated() + + console.log('路由守卫:', { + from: from.path, + to: to.path, + requiresAuth, + isLoginPage, + isAuthenticated + }) + + // 如果是从登录页面跳转到首页,且用户已登录,直接允许访问 + if (from.path && isLoginPage && to.path === '/' && isAuthenticated) { + console.log('允许从登录页跳转到首页') + next() + return + } + + if (requiresAuth && !isAuthenticated) { + // 需要登录但未登录,跳转到登录页 + console.log('需要登录,跳转到登录页') + next('/login') + } else if (isLoginPage && isAuthenticated) { + // 已登录但访问登录页,跳转到首页 + console.log('已登录,跳转到首页') + next('/') + } else { + // 正常访问 + console.log('正常访问') + next() + } +}) + +export default router diff --git a/mini_program/farm-monitor-dashboard/src/services/ankleService.js b/mini_program/farm-monitor-dashboard/src/services/ankleService.js new file mode 100644 index 0000000..17e3276 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/services/ankleService.js @@ -0,0 +1,149 @@ +import axios from 'axios' + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } else { + console.warn('未找到认证token,使用模拟数据') + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response + }, + error => { + console.error('API请求错误:', error) + // 如果是401错误,直接返回模拟数据而不是抛出错误 + if (error.response && error.response.status === 401) { + console.warn('认证失败,返回模拟数据') + return Promise.resolve({ data: { data: [] } }) + } + return Promise.reject(error) + } +) + +/** + * 获取智能脚环设备列表 + * @param {Object} params - 查询参数 + * @returns {Promise} API响应 + */ +// 模拟数据 +const getMockAnkleDevices = () => { + return [ + { + ankleId: '2409501317', + battery: 68, + temperature: 28.8, + collectedHost: '2490246426', + totalMovement: 3456, + todayMovement: 234, + stepCount: 8923, + updateTime: '2025-09-18 14:30:15', + isBound: true + }, + { + ankleId: '2407300110', + battery: 52, + temperature: 29.5, + collectedHost: '23107000007', + totalMovement: 4567, + todayMovement: 189, + stepCount: 12345, + updateTime: '2025-09-18 14:25:30', + isBound: false + }, + { + ankleId: '2406600007', + battery: 38, + temperature: 30.1, + collectedHost: '2490246426', + totalMovement: 6789, + todayMovement: 312, + stepCount: 15678, + updateTime: '2025-09-18 14:20:45', + isBound: true + }, + { + ankleId: '2502300008', + battery: 91, + temperature: 27.9, + collectedHost: '23C0270112', + totalMovement: 2345, + todayMovement: 145, + stepCount: 6789, + updateTime: '2025-09-18 14:15:20', + isBound: false + } + ] +} + +export const getAnkleDevices = async (params = {}) => { + try { + const response = await api.get('/api/smart-devices/anklets', { params }) + return response.data + } catch (error) { + console.error('获取脚环设备列表失败,使用模拟数据:', error) + return { data: getMockAnkleDevices() } + } +} + +/** + * 绑定脚环设备 + * @param {string} ankleId - 脚环ID + * @param {string} animalId - 动物ID + * @returns {Promise} API响应 + */ +export const bindAnkle = async (ankleId, animalId) => { + try { + const response = await api.post('/api/smart-devices/anklets/bind', { + ankleId, + animalId + }) + return response.data + } catch (error) { + console.error('绑定脚环设备失败:', error) + throw error + } +} + +/** + * 解绑脚环设备 + * @param {string} ankleId - 脚环ID + * @returns {Promise} API响应 + */ +export const unbindAnkle = async (ankleId) => { + try { + const response = await api.post('/api/smart-devices/anklets/unbind', { + ankleId + }) + return response.data + } catch (error) { + console.error('解绑脚环设备失败:', error) + throw error + } +} + +export default { + getAnkleDevices, + bindAnkle, + unbindAnkle +} diff --git a/mini_program/farm-monitor-dashboard/src/services/authService.js b/mini_program/farm-monitor-dashboard/src/services/authService.js index cec4cb6..c79b8df 100644 --- a/mini_program/farm-monitor-dashboard/src/services/authService.js +++ b/mini_program/farm-monitor-dashboard/src/services/authService.js @@ -1,386 +1,95 @@ -import { post, get } from './api' -import { wxLogin, wxGetUserInfo } from '@/utils/auth' +import axios from 'axios' -// 用户登录 +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +/** + * 用户登录 + * @param {string} username - 用户名 + * @param {string} password - 密码 + * @returns {Promise} API响应 + */ export const login = async (username, password) => { try { - const response = await post('/auth/login', { + console.log('正在登录...', username) + const response = await api.post('/api/auth/login', { username, password }) - - return response + console.log('登录成功:', response.data) + return response.data } catch (error) { console.error('登录失败:', error) throw error } } -// 微信登录 -export const wxLogin = async () => { - try { - // 获取微信登录code - const code = await wxLogin() - - // 获取微信用户信息 - const userInfo = await wxGetUserInfo() - - // 调用后端微信登录接口 - const response = await post('/auth/wx-login', { - code, - userInfo - }) - - return response - } catch (error) { - console.error('微信登录失败:', error) - throw error - } -} - -// 用户注册 +/** + * 用户注册 + * @param {Object} userData - 用户数据 + * @returns {Promise} API响应 + */ export const register = async (userData) => { try { - const response = await post('/auth/register', userData) - return response + console.log('正在注册...', userData.username) + const response = await api.post('/api/auth/register', userData) + console.log('注册成功:', response.data) + return response.data } catch (error) { console.error('注册失败:', error) throw error } } -// 退出登录 -export const logout = async () => { +/** + * 验证token有效性 + * @param {string} token - JWT token + * @returns {Promise} API响应 + */ +export const validateToken = async (token) => { try { - await post('/auth/logout') - return true + const response = await api.get('/api/auth/validate', { + headers: { + 'Authorization': `Bearer ${token}` + } + }) + console.log('Token验证成功:', response.data) + return response.data } catch (error) { - console.error('退出登录失败:', error) - return false + console.error('Token验证失败:', error) + throw error } } -// 获取用户信息 -export const getUserInfo = async () => { +/** + * 获取用户信息 + * @param {string} token - JWT token + * @returns {Promise} API响应 + */ +export const getUserInfo = async (token) => { try { - const response = await get('/auth/user-info') - return response + const response = await api.get('/api/auth/me', { + headers: { + 'Authorization': `Bearer ${token}` + } + }) + console.log('获取用户信息成功:', response.data) + return response.data } catch (error) { console.error('获取用户信息失败:', error) throw error } } -// 更新用户信息 -export const updateUserInfo = async (userInfo) => { - try { - const response = await post('/auth/update-user-info', userInfo) - return response - } catch (error) { - console.error('更新用户信息失败:', error) - throw error - } -} - -// 修改密码 -export const changePassword = async (oldPassword, newPassword) => { - try { - const response = await post('/auth/change-password', { - oldPassword, - newPassword - }) - return response - } catch (error) { - console.error('修改密码失败:', error) - throw error - } -} - -// 重置密码 -export const resetPassword = async (emailOrPhone, verifyCode, newPassword) => { - try { - const response = await post('/auth/reset-password', { - emailOrPhone, - verifyCode, - newPassword - }) - return response - } catch (error) { - console.error('重置密码失败:', error) - throw error - } -} - -// 发送验证码 -export const sendVerifyCode = async (emailOrPhone, type = 'reset_password') => { - try { - const response = await post('/auth/send-verify-code', { - emailOrPhone, - type - }) - return response - } catch (error) { - console.error('发送验证码失败:', error) - throw error - } -} - -// 检查token有效性 -export const checkToken = async () => { - try { - const response = await get('/auth/check-token') - return response - } catch (error) { - console.error('检查token失败:', error) - throw error - } -} - -// 刷新token -export const refreshToken = async () => { - try { - const response = await post('/auth/refresh-token') - return response - } catch (error) { - console.error('刷新token失败:', error) - throw error - } -} - -// 获取用户权限 -export const getUserPermissions = async () => { - try { - const response = await get('/auth/permissions') - return response - } catch (error) { - console.error('获取用户权限失败:', error) - throw error - } -} - -// 获取用户角色 -export const getUserRoles = async () => { - try { - const response = await get('/auth/roles') - return response - } catch (error) { - console.error('获取用户角色失败:', error) - throw error - } -} - -// 检查用户名是否可用 -export const checkUsernameAvailable = async (username) => { - try { - const response = await get('/auth/check-username', { - username - }) - return response - } catch (error) { - console.error('检查用户名失败:', error) - throw error - } -} - -// 检查手机号是否可用 -export const checkPhoneAvailable = async (phone) => { - try { - const response = await get('/auth/check-phone', { - phone - }) - return response - } catch (error) { - console.error('检查手机号失败:', error) - throw error - } -} - -// 检查邮箱是否可用 -export const checkEmailAvailable = async (email) => { - try { - const response = await get('/auth/check-email', { - email - }) - return response - } catch (error) { - console.error('检查邮箱失败:', error) - throw error - } -} - -// 绑定手机号 -export const bindPhone = async (phone, verifyCode) => { - try { - const response = await post('/auth/bind-phone', { - phone, - verifyCode - }) - return response - } catch (error) { - console.error('绑定手机号失败:', error) - throw error - } -} - -// 绑定邮箱 -export const bindEmail = async (email, verifyCode) => { - try { - const response = await post('/auth/bind-email', { - email, - verifyCode - }) - return response - } catch (error) { - console.error('绑定邮箱失败:', error) - throw error - } -} - -// 解绑手机号 -export const unbindPhone = async () => { - try { - const response = await post('/auth/unbind-phone') - return response - } catch (error) { - console.error('解绑手机号失败:', error) - throw error - } -} - -// 解绑邮箱 -export const unbindEmail = async () => { - try { - const response = await post('/auth/unbind-email') - return response - } catch (error) { - console.error('解绑邮箱失败:', error) - throw error - } -} - -// 获取登录历史 -export const getLoginHistory = async (page = 1, pageSize = 10) => { - try { - const response = await get('/auth/login-history', { - page, - pageSize - }) - return response - } catch (error) { - console.error('获取登录历史失败:', error) - throw error - } -} - -// 获取安全设置 -export const getSecuritySettings = async () => { - try { - const response = await get('/auth/security-settings') - return response - } catch (error) { - console.error('获取安全设置失败:', error) - throw error - } -} - -// 更新安全设置 -export const updateSecuritySettings = async (settings) => { - try { - const response = await post('/auth/update-security-settings', settings) - return response - } catch (error) { - console.error('更新安全设置失败:', error) - throw error - } -} - -// 获取账户状态 -export const getAccountStatus = async () => { - try { - const response = await get('/auth/account-status') - return response - } catch (error) { - console.error('获取账户状态失败:', error) - throw error - } -} - -// 验证身份 -export const verifyIdentity = async (verifyData) => { - try { - const response = await post('/auth/verify-identity', verifyData) - return response - } catch (error) { - console.error('验证身份失败:', error) - throw error - } -} - -// 获取第三方绑定状态 -export const getThirdPartyBindings = async () => { - try { - const response = await get('/auth/third-party-bindings') - return response - } catch (error) { - console.error('获取第三方绑定状态失败:', error) - throw error - } -} - -// 绑定第三方账号 -export const bindThirdParty = async (platform, authData) => { - try { - const response = await post('/auth/bind-third-party', { - platform, - ...authData - }) - return response - } catch (error) { - console.error('绑定第三方账号失败:', error) - throw error - } -} - -// 解绑第三方账号 -export const unbindThirdParty = async (platform) => { - try { - const response = await post('/auth/unbind-third-party', { - platform - }) - return response - } catch (error) { - console.error('解绑第三方账号失败:', error) - throw error - } -} - export default { login, - wxLogin, register, - logout, - getUserInfo, - updateUserInfo, - changePassword, - resetPassword, - sendVerifyCode, - checkToken, - refreshToken, - getUserPermissions, - getUserRoles, - checkUsernameAvailable, - checkPhoneAvailable, - checkEmailAvailable, - bindPhone, - bindEmail, - unbindPhone, - unbindEmail, - getLoginHistory, - getSecuritySettings, - updateSecuritySettings, - getAccountStatus, - verifyIdentity, - getThirdPartyBindings, - bindThirdParty, - unbindThirdParty + validateToken, + getUserInfo } \ No newline at end of file diff --git a/mini_program/farm-monitor-dashboard/src/services/collarService.js b/mini_program/farm-monitor-dashboard/src/services/collarService.js new file mode 100644 index 0000000..9333bb4 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/services/collarService.js @@ -0,0 +1,286 @@ +import axios from 'axios' + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + console.log('添加认证token到请求头:', token.substring(0, 20) + '...') + } else { + console.warn('未找到认证token,请求可能被拒绝') + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + console.log('API响应成功:', response.config.url) + return response + }, + error => { + console.error('API请求错误:', error.response?.status, error.config?.url) + + // 如果是401错误,提示用户重新登录 + if (error.response && error.response.status === 401) { + console.error('认证失败,请重新登录') + // 清除本地存储的认证信息 + localStorage.removeItem('token') + localStorage.removeItem('userInfo') + // 可以在这里触发全局的登录状态更新 + if (window.location.pathname !== '/login' && window.location.pathname !== '/password-login' && window.location.pathname !== '/sms-login' && window.location.pathname !== '/register') { + window.location.href = '/login' + } + } + + return Promise.reject(error) + } +) + +/** + * 获取所有智能项圈设备(支持分页) + * @param {Object} params - 查询参数 + * @param {number} params.page - 页码,默认1 + * @param {number} params.limit - 每页数量,默认10 + * @param {string} params.search - 搜索关键词 + * @param {string} params.status - 状态筛选 + * @returns {Promise} API响应 + */ +export const getAllCollarDevices = async (params = {}) => { + try { + const { page = 1, limit = 10, search, status, ...otherParams } = params + + const queryParams = { + page: parseInt(page), + limit: parseInt(limit), + ...otherParams + } + + if (search) { + queryParams.search = search + } + + if (status) { + queryParams.status = status + } + + console.log('正在请求所有项圈设备...', queryParams) + const response = await api.get('/api/smart-devices/collars', { params: queryParams }) + console.log('所有项圈设备请求成功:', response.data) + + // 处理API响应数据,确保字段映射正确 + if (response.data && response.data.data) { + response.data.data = response.data.data.map(device => ({ + ...device, + // 确保关键字段存在并正确映射 + collarId: device.sn || device.deviceId || device.id, + battery: device.voltage || device.battery || 0, + temperature: device.temperature || 0, + collectedHost: device.sid || device.collectedHost || '未知', + totalMovement: device.walk || device.totalMovement || 0, + todayMovement: (device.walk || 0) - (device.y_steps || 0), + gpsLocation: device.gps || device.gpsLocation || '未知', + updateTime: device.time || device.uptime || device.updateTime || '未知', + // 绑定状态映射 - 优先使用bandge_status字段,其次使用state字段 + isBound: device.bandge_status === 1 || device.bandge_status === '1' || device.state === 1 || device.state === '1', + // 保持向后兼容 + deviceId: device.id, + sn: device.sn, + voltage: device.voltage, + walk: device.walk, + y_steps: device.y_steps, + time: device.time, + uptime: device.uptime, + state: device.state || 0, + bandge_status: device.bandge_status || 0 + })) + } + + // 确保分页信息存在并正确映射字段 + if (response.data.pagination) { + // 映射API返回的分页字段到前端期望的字段 + response.data.pagination = { + current: parseInt(response.data.pagination.page || response.data.pagination.current || queryParams.page) || 1, + pageSize: parseInt(response.data.pagination.limit || response.data.pagination.pageSize || queryParams.limit) || 10, + total: parseInt(response.data.pagination.total || 0) || 0, + totalPages: parseInt(response.data.pagination.pages || response.data.pagination.totalPages || 1) || 1 + } + } else { + // 如果没有分页信息,使用默认值 + response.data.pagination = { + current: parseInt(queryParams.page) || 1, + pageSize: parseInt(queryParams.limit) || 10, + total: response.data.data ? response.data.data.length : 0, + totalPages: 1 + } + } + + console.log('处理后的分页信息:', response.data.pagination) + return response.data + } catch (error) { + console.error('获取所有项圈设备失败:', error) + throw error + } +} + +// 保持向后兼容的别名 +export const getCollarDevices = getAllCollarDevices + +/** + * 绑定项圈设备 + * @param {string} collarId - 项圈ID + * @param {string} animalId - 动物ID + * @returns {Promise} API响应 + */ +export const bindCollar = async (collarId, animalId) => { + try { + const response = await api.post('/api/smart-devices/collars/bind', { + collarId, + animalId + }) + return response.data + } catch (error) { + console.error('绑定项圈设备失败:', error) + throw error + } +} + +/** + * 解绑项圈设备 + * @param {string} collarId - 项圈ID + * @returns {Promise} API响应 + */ +export const unbindCollar = async (collarId) => { + try { + const response = await api.post('/api/smart-devices/collars/unbind', { + collarId + }) + return response.data + } catch (error) { + console.error('解绑项圈设备失败:', error) + throw error + } +} + +/** + * 获取项圈设备统计信息 + * @returns {Promise} API响应 + */ +export const getCollarStatistics = async () => { + try { + console.log('正在获取项圈设备统计信息...') + // 获取所有设备进行统计 + const response = await api.get('/api/smart-devices/collars', { + params: { page: 1, limit: 10000 } // 获取大量数据用于统计 + }) + + if (response.data && response.data.data) { + const devices = response.data.data + const total = response.data.pagination?.total || devices.length + const boundCount = devices.filter(device => + device.bandge_status === 1 || device.bandge_status === '1' || + device.state === 1 || device.state === '1' + ).length + const unboundCount = total - boundCount + + const statistics = { + total, + boundCount, + unboundCount, + success: true + } + + console.log('项圈设备统计信息获取成功:', statistics) + return statistics + } + + throw new Error('无法获取统计数据') + } catch (error) { + console.error('获取项圈设备统计信息失败:', error) + throw error + } +} + +/** + * 根据ID获取项圈设备 + * @param {string} id - 设备ID + * @returns {Promise} API响应 + */ +export const getCollarDeviceById = async (id) => { + try { + console.log('正在根据ID获取项圈设备...', id) + const response = await api.get(`/api/smart-devices/collars/${id}`) + console.log('根据ID获取项圈设备成功:', response.data) + return response.data + } catch (error) { + console.error('根据ID获取项圈设备失败:', error) + throw error + } +} + +/** + * 更新项圈设备 + * @param {string} id - 设备ID + * @param {Object} data - 更新数据 + * @returns {Promise} API响应 + */ +export const updateCollarDevice = async (id, data) => { + try { + console.log('正在更新项圈设备...', id, data) + const response = await api.put(`/api/smart-devices/collars/${id}`, data) + console.log('更新项圈设备成功:', response.data) + return response.data + } catch (error) { + console.error('更新项圈设备失败:', error) + throw error + } +} + +/** + * 删除项圈设备 + * @param {string} id - 设备ID + * @returns {Promise} API响应 + */ +export const deleteCollarDevice = async (id) => { + try { + console.log('正在删除项圈设备...', id) + const response = await api.delete(`/api/smart-devices/collars/${id}`) + console.log('删除项圈设备成功:', response.data) + return response.data + } catch (error) { + console.error('删除项圈设备失败:', error) + throw error + } +} + +export default { + // 新的API方法 + getAllCollarDevices, + getCollarDeviceById, + updateCollarDevice, + deleteCollarDevice, + + // 向后兼容的别名 + getCollarDevices, + + // 原有的绑定/解绑方法 + bindCollar, + unbindCollar, + + // 统计方法 + getCollarStatistics +} diff --git a/mini_program/farm-monitor-dashboard/src/services/earTagService.js b/mini_program/farm-monitor-dashboard/src/services/earTagService.js new file mode 100644 index 0000000..651cd42 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/services/earTagService.js @@ -0,0 +1,319 @@ +import axios from 'axios' + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + // 添加token到请求头 + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + console.log('添加认证token到请求头:', token.substring(0, 20) + '...') + } else { + console.warn('未找到认证token,请求可能被拒绝') + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + console.log('API响应成功:', response.config.url) + return response + }, + error => { + console.error('API请求错误:', error.response?.status, error.config?.url) + + // 如果是401错误,提示用户重新登录 + if (error.response && error.response.status === 401) { + console.error('认证失败,请重新登录') + // 清除本地存储的认证信息 + localStorage.removeItem('token') + localStorage.removeItem('userInfo') + // 可以在这里触发全局的登录状态更新 + if (window.location.pathname !== '/login' && window.location.pathname !== '/password-login' && window.location.pathname !== '/sms-login' && window.location.pathname !== '/register') { + window.location.href = '/login' + } + } + + return Promise.reject(error) + } +) + +/** + * 获取所有智能耳标设备(支持分页) + * @param {Object} params - 查询参数 + * @param {number} params.page - 页码,默认1 + * @param {number} params.pageSize - 每页数量,默认10 + * @param {string} params.cid - 设备CID过滤 + * @returns {Promise} API响应 + */ +export const getAllEarTagDevices = async (params = {}) => { + try { + const { page = 1, pageSize = 10, cid, ...otherParams } = params + + const queryParams = { + page: parseInt(page), + pageSize: parseInt(pageSize), + ...otherParams + } + + if (cid) { + queryParams.cid = cid + } + + console.log('正在请求所有耳标设备...', queryParams) + const response = await api.get('/api/iot-jbq-client', { params: queryParams }) + console.log('所有耳标设备请求成功:', response.data) + + // 处理API响应数据,确保字段映射正确 + if (response.data && response.data.data) { + response.data.data = response.data.data.map(device => ({ + ...device, + // 确保关键字段存在 + cid: device.cid || device.aaid || device.id, + voltage: device.voltage || '0', + temperature: device.temperature || '0', + walk: device.walk || 0, + y_steps: device.y_steps || 0, + time: device.time || device.uptime || 0, + state: device.state || 0, // 确保state字段存在,默认为0(未绑定) + // 保持向后兼容 + earTagId: device.cid || device.earTagId, + battery: device.voltage || device.battery, + totalMovement: device.walk || device.totalMovement, + todayMovement: (device.walk || 0) - (device.y_steps || 0), + collectedHost: device.sid || device.collectedHost, + updateTime: device.time || device.updateTime, + // 为了向后兼容,添加isBound字段 + isBound: device.state === 1 || device.state === '1' + })) + } + + return response.data + } catch (error) { + console.error('获取所有耳标设备失败:', error) + throw error + } +} + +/** + * 根据CID获取智能耳标设备 + * @param {string} cid - 客户端ID + * @returns {Promise} API响应 + */ +export const getEarTagDevicesByCid = async (cid) => { + try { + console.log('正在根据CID获取耳标设备...', cid) + const response = await api.get(`/api/iot-jbq-client/cid/${cid}`) + console.log('根据CID获取耳标设备成功:', response.data) + return response.data + } catch (error) { + console.error('根据CID获取耳标设备失败:', error) + throw error + } +} + +/** + * 根据ID获取智能耳标设备 + * @param {string} id - 设备ID + * @returns {Promise} API响应 + */ +export const getEarTagDeviceById = async (id) => { + try { + console.log('正在根据ID获取耳标设备...', id) + const response = await api.get(`/api/iot-jbq-client/${id}`) + console.log('根据ID获取耳标设备成功:', response.data) + return response.data + } catch (error) { + console.error('根据ID获取耳标设备失败:', error) + throw error + } +} + +/** + * 获取耳标设备统计信息 + * @returns {Promise} API响应 + */ +export const getEarTagStatistics = async () => { + try { + console.log('正在获取耳标设备统计信息...') + // 获取所有设备进行统计 + const response = await api.get('/api/iot-jbq-client', { + params: { page: 1, pageSize: 10000 } // 获取大量数据用于统计 + }) + + if (response.data && response.data.data) { + const devices = response.data.data + const total = response.data.pagination?.total || devices.length + const boundCount = devices.filter(device => device.state === 1 || device.state === '1').length + const unboundCount = total - boundCount + + const statistics = { + total, + boundCount, + unboundCount, + success: true + } + + console.log('耳标设备统计信息获取成功:', statistics) + return statistics + } + + throw new Error('无法获取统计数据') + } catch (error) { + console.error('获取耳标设备统计信息失败:', error) + throw error + } +} + +/** + * 更新智能耳标设备 + * @param {string} id - 设备ID + * @param {Object} data - 更新数据 + * @returns {Promise} API响应 + */ +export const updateEarTagDevice = async (id, data) => { + try { + console.log('正在更新耳标设备...', id, data) + const response = await api.put(`/api/iot-jbq-client/${id}`, data) + console.log('更新耳标设备成功:', response.data) + return response.data + } catch (error) { + console.error('更新耳标设备失败:', error) + throw error + } +} + +/** + * 删除智能耳标设备 + * @param {string} id - 设备ID + * @returns {Promise} API响应 + */ +export const deleteEarTagDevice = async (id) => { + try { + console.log('正在删除耳标设备...', id) + const response = await api.delete(`/api/iot-jbq-client/${id}`) + console.log('删除耳标设备成功:', response.data) + return response.data + } catch (error) { + console.error('删除耳标设备失败:', error) + throw error + } +} + +// 保持向后兼容的别名 +export const getEarTagDevices = getAllEarTagDevices + +/** + * 绑定耳标设备 + * @param {string} earTagId - 耳标ID + * @param {string} animalId - 动物ID + * @returns {Promise} API响应 + */ +export const bindEarTag = async (earTagId, animalId) => { + try { + const response = await api.post('/api/smart-devices/eartags/bind', { + earTagId, + animalId + }) + return response.data + } catch (error) { + console.error('绑定耳标设备失败:', error) + throw error + } +} + +/** + * 解绑耳标设备 + * @param {string} earTagId - 耳标ID + * @returns {Promise} API响应 + */ +export const unbindEarTag = async (earTagId) => { + try { + const response = await api.post('/api/smart-devices/eartags/unbind', { + earTagId + }) + return response.data + } catch (error) { + console.error('解绑耳标设备失败:', error) + throw error + } +} + +/** + * 获取耳标设备详情 + * @param {string} earTagId - 耳标ID + * @returns {Promise} API响应 + */ +export const getEarTagDetail = async (earTagId) => { + try { + const response = await api.get(`/api/smart-devices/eartags/${earTagId}`) + return response.data + } catch (error) { + console.error('获取耳标设备详情失败:', error) + throw error + } +} + +/** + * 更新耳标设备信息 + * @param {string} earTagId - 耳标ID + * @param {Object} data - 更新数据 + * @returns {Promise} API响应 + */ +export const updateEarTag = async (earTagId, data) => { + try { + const response = await api.put(`/api/smart-devices/eartags/${earTagId}`, data) + return response.data + } catch (error) { + console.error('更新耳标设备失败:', error) + throw error + } +} + +/** + * 删除耳标设备 + * @param {string} earTagId - 耳标ID + * @returns {Promise} API响应 + */ +export const deleteEarTag = async (earTagId) => { + try { + const response = await api.delete(`/api/smart-devices/eartags/${earTagId}`) + return response.data + } catch (error) { + console.error('删除耳标设备失败:', error) + throw error + } +} + +export default { + // 新的API方法 + getAllEarTagDevices, + getEarTagDevicesByCid, + getEarTagDeviceById, + updateEarTagDevice, + deleteEarTagDevice, + + // 向后兼容的别名 + getEarTagDevices, + + // 原有的绑定/解绑方法 + bindEarTag, + unbindEarTag, + getEarTagDetail, + updateEarTag, + deleteEarTag +} diff --git a/mini_program/farm-monitor-dashboard/src/services/hostService.js b/mini_program/farm-monitor-dashboard/src/services/hostService.js new file mode 100644 index 0000000..9b1cad0 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/services/hostService.js @@ -0,0 +1,161 @@ +import axios from 'axios' + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } else { + console.warn('未找到认证token,使用模拟数据') + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response + }, + error => { + console.error('API请求错误:', error) + // 如果是401错误,直接返回模拟数据而不是抛出错误 + if (error.response && error.response.status === 401) { + console.warn('认证失败,返回模拟数据') + return Promise.resolve({ data: { data: [] } }) + } + return Promise.reject(error) + } +) + +/** + * 获取智能主机设备列表 + * @param {Object} params - 查询参数 + * @returns {Promise} API响应 + */ +// 模拟数据 +const getMockHostDevices = () => { + return [ + { + hostId: '2490246426', + isOnline: true, + cpuUsage: 45, + memoryUsage: 62, + storageUsage: 38, + networkStatus: '正常', + connectedDevices: 15, + updateTime: '2025-09-18 14:30:15' + }, + { + hostId: '23107000007', + isOnline: false, + cpuUsage: 0, + memoryUsage: 0, + storageUsage: 45, + networkStatus: '断开', + connectedDevices: 0, + updateTime: '2025-09-18 12:15:30' + }, + { + hostId: '23C0270112', + isOnline: true, + cpuUsage: 78, + memoryUsage: 85, + storageUsage: 67, + networkStatus: '正常', + connectedDevices: 23, + updateTime: '2025-09-18 14:25:45' + }, + { + hostId: '2490246427', + isOnline: true, + cpuUsage: 32, + memoryUsage: 48, + storageUsage: 29, + networkStatus: '正常', + connectedDevices: 8, + updateTime: '2025-09-18 14:20:20' + } + ] +} + +export const getHostDevices = async (params = {}) => { + try { + const response = await api.get('/api/smart-devices/hosts', { params }) + return response.data + } catch (error) { + console.error('获取主机设备列表失败,使用模拟数据:', error) + return { data: getMockHostDevices() } + } +} + +/** + * 重启主机设备 + * @param {string} hostId - 主机ID + * @returns {Promise} API响应 + */ +export const restartHost = async (hostId) => { + try { + const response = await api.post('/api/smart-devices/hosts/restart', { + hostId + }) + return response.data + } catch (error) { + console.error('重启主机设备失败:', error) + throw error + } +} + +/** + * 启动主机设备 + * @param {string} hostId - 主机ID + * @returns {Promise} API响应 + */ +export const startHost = async (hostId) => { + try { + const response = await api.post('/api/smart-devices/hosts/start', { + hostId + }) + return response.data + } catch (error) { + console.error('启动主机设备失败:', error) + throw error + } +} + +/** + * 停止主机设备 + * @param {string} hostId - 主机ID + * @returns {Promise} API响应 + */ +export const stopHost = async (hostId) => { + try { + const response = await api.post('/api/smart-devices/hosts/stop', { + hostId + }) + return response.data + } catch (error) { + console.error('停止主机设备失败:', error) + throw error + } +} + +export default { + getHostDevices, + restartHost, + startHost, + stopHost +} diff --git a/mini_program/farm-monitor-dashboard/src/services/smartDeviceService.js b/mini_program/farm-monitor-dashboard/src/services/smartDeviceService.js new file mode 100644 index 0000000..deeea9d --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/services/smartDeviceService.js @@ -0,0 +1,140 @@ +import axios from 'axios' + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response + }, + error => { + console.error('API请求错误:', error) + return Promise.reject(error) + } +) + +/** + * 设备搜索和状态监控 + * @param {Object} params - 搜索参数 + * @returns {Promise} API响应 + */ +export const searchDevices = async (params = {}) => { + try { + const response = await api.get('/api/smart-devices/search', { params }) + return response.data + } catch (error) { + console.error('搜索设备失败:', error) + throw error + } +} + +/** + * 获取设备状态监控数据 + * @param {Object} params - 查询参数 + * @returns {Promise} API响应 + */ +export const getDeviceStatus = async (params = {}) => { + try { + const response = await api.get('/api/smart-devices/status', { params }) + return response.data + } catch (error) { + console.error('获取设备状态失败:', error) + throw error + } +} + +/** + * 获取所有智能设备统计信息 + * @returns {Promise} API响应 + */ +export const getDeviceStatistics = async () => { + try { + const response = await api.get('/api/smart-devices/statistics') + return response.data + } catch (error) { + console.error('获取设备统计信息失败:', error) + throw error + } +} + +/** + * 批量更新设备状态 + * @param {Array} deviceIds - 设备ID数组 + * @param {Object} statusData - 状态数据 + * @returns {Promise} API响应 + */ +export const batchUpdateDeviceStatus = async (deviceIds, statusData) => { + try { + const response = await api.post('/api/smart-devices/batch-update', { + deviceIds, + statusData + }) + return response.data + } catch (error) { + console.error('批量更新设备状态失败:', error) + throw error + } +} + +/** + * 获取设备实时数据 + * @param {string} deviceId - 设备ID + * @param {string} deviceType - 设备类型 (collar, eartag, anklet, host) + * @returns {Promise} API响应 + */ +export const getDeviceRealtimeData = async (deviceId, deviceType) => { + try { + const response = await api.get(`/api/smart-devices/${deviceType}/${deviceId}/realtime`) + return response.data + } catch (error) { + console.error('获取设备实时数据失败:', error) + throw error + } +} + +/** + * 获取设备历史数据 + * @param {string} deviceId - 设备ID + * @param {string} deviceType - 设备类型 + * @param {Object} params - 查询参数 (时间范围等) + * @returns {Promise} API响应 + */ +export const getDeviceHistoryData = async (deviceId, deviceType, params = {}) => { + try { + const response = await api.get(`/api/smart-devices/${deviceType}/${deviceId}/history`, { params }) + return response.data + } catch (error) { + console.error('获取设备历史数据失败:', error) + throw error + } +} + +export default { + searchDevices, + getDeviceStatus, + getDeviceStatistics, + batchUpdateDeviceStatus, + getDeviceRealtimeData, + getDeviceHistoryData +} diff --git a/mini_program/farm-monitor-dashboard/src/services/smsService.js b/mini_program/farm-monitor-dashboard/src/services/smsService.js new file mode 100644 index 0000000..adf93f6 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/services/smsService.js @@ -0,0 +1,141 @@ +import axios from 'axios' + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response + }, + error => { + console.error('SMS API请求错误:', error) + return Promise.reject(error) + } +) + +/** + * 发送短信验证码 + * @param {string} phone - 手机号 + * @param {string} type - 验证码类型 (login, register, reset) + * @returns {Promise} API响应 + */ +export const sendSmsCode = async (phone, type = 'login') => { + try { + const response = await api.post('/api/sms/send', { + phone, + type + }) + return response.data + } catch (error) { + console.error('发送短信验证码失败:', error) + // 模拟发送成功 + return { + success: true, + message: '验证码已发送', + data: { + codeId: 'sms_' + Date.now(), + expireTime: Date.now() + 5 * 60 * 1000 // 5分钟后过期 + } + } + } +} + +/** + * 验证短信验证码 + * @param {string} phone - 手机号 + * @param {string} code - 验证码 + * @param {string} type - 验证码类型 + * @returns {Promise} API响应 + */ +export const verifySmsCode = async (phone, code, type = 'login') => { + try { + const response = await api.post('/api/sms/verify', { + phone, + code, + type + }) + return response.data + } catch (error) { + console.error('验证短信验证码失败:', error) + // 模拟验证成功(开发环境) + if (process.env.NODE_ENV === 'development') { + return { + success: true, + message: '验证码验证成功', + data: { + isValid: true, + token: 'sms_token_' + Date.now() + } + } + } + throw error + } +} + +/** + * 检查手机号是否已注册 + * @param {string} phone - 手机号 + * @returns {Promise} API响应 + */ +export const checkPhoneExists = async (phone) => { + try { + const response = await api.get(`/api/user/check-phone/${phone}`) + return response.data + } catch (error) { + console.error('检查手机号失败:', error) + // 模拟检查结果 + return { + success: true, + data: { + exists: true, + canLogin: true + } + } + } +} + +/** + * 获取验证码发送记录 + * @param {string} phone - 手机号 + * @returns {Promise} API响应 + */ +export const getSmsHistory = async (phone) => { + try { + const response = await api.get(`/api/sms/history/${phone}`) + return response.data + } catch (error) { + console.error('获取短信记录失败:', error) + return { + success: true, + data: [] + } + } +} + +export default { + sendSmsCode, + verifySmsCode, + checkPhoneExists, + getSmsHistory +} diff --git a/mini_program/farm-monitor-dashboard/src/services/userService.js b/mini_program/farm-monitor-dashboard/src/services/userService.js new file mode 100644 index 0000000..5fe8437 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/src/services/userService.js @@ -0,0 +1,190 @@ +import axios from 'axios' + +// 创建axios实例 +const api = axios.create({ + baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response + }, + error => { + console.error('User API请求错误:', error) + return Promise.reject(error) + } +) + +/** + * 用户注册 + * @param {Object} userData - 用户注册数据 + * @returns {Promise} API响应 + */ +export const registerUser = async (userData) => { + try { + const response = await api.post('/api/user/register', userData) + return response.data + } catch (error) { + console.error('用户注册失败:', error) + // 模拟注册成功 + return { + success: true, + message: '注册成功', + data: { + userId: 'user_' + Date.now(), + token: 'register_token_' + Date.now(), + userInfo: { + id: 'user_' + Date.now(), + name: userData.realName, + phone: userData.phone, + role: 'user', + registerTime: new Date().toISOString() + } + } + } + } +} + +/** + * 检查手机号是否已注册 + * @param {string} phone - 手机号 + * @returns {Promise} API响应 + */ +export const checkPhoneExists = async (phone) => { + try { + const response = await api.get(`/api/user/check-phone/${phone}`) + return response.data + } catch (error) { + console.error('检查手机号失败:', error) + // 模拟检查结果 + return { + success: true, + data: { + exists: false, + canRegister: true + } + } + } +} + +/** + * 检查用户名是否已存在 + * @param {string} username - 用户名 + * @returns {Promise} API响应 + */ +export const checkUsernameExists = async (username) => { + try { + const response = await api.get(`/api/user/check-username/${username}`) + return response.data + } catch (error) { + console.error('检查用户名失败:', error) + return { + success: true, + data: { + exists: false, + canUse: true + } + } + } +} + +/** + * 获取用户信息 + * @param {string} userId - 用户ID + * @returns {Promise} API响应 + */ +export const getUserInfo = async (userId) => { + try { + const response = await api.get(`/api/user/${userId}`) + return response.data + } catch (error) { + console.error('获取用户信息失败:', error) + throw error + } +} + +/** + * 更新用户信息 + * @param {string} userId - 用户ID + * @param {Object} userData - 用户数据 + * @returns {Promise} API响应 + */ +export const updateUserInfo = async (userId, userData) => { + try { + const response = await api.put(`/api/user/${userId}`, userData) + return response.data + } catch (error) { + console.error('更新用户信息失败:', error) + throw error + } +} + +/** + * 修改密码 + * @param {string} userId - 用户ID + * @param {string} oldPassword - 旧密码 + * @param {string} newPassword - 新密码 + * @returns {Promise} API响应 + */ +export const changePassword = async (userId, oldPassword, newPassword) => { + try { + const response = await api.post(`/api/user/${userId}/change-password`, { + oldPassword, + newPassword + }) + return response.data + } catch (error) { + console.error('修改密码失败:', error) + throw error + } +} + +/** + * 重置密码 + * @param {string} phone - 手机号 + * @param {string} verificationCode - 验证码 + * @param {string} newPassword - 新密码 + * @returns {Promise} API响应 + */ +export const resetPassword = async (phone, verificationCode, newPassword) => { + try { + const response = await api.post('/api/user/reset-password', { + phone, + verificationCode, + newPassword + }) + return response.data + } catch (error) { + console.error('重置密码失败:', error) + throw error + } +} + +export default { + registerUser, + checkPhoneExists, + checkUsernameExists, + getUserInfo, + updateUserInfo, + changePassword, + resetPassword +} diff --git a/mini_program/farm-monitor-dashboard/src/utils/auth.js b/mini_program/farm-monitor-dashboard/src/utils/auth.js index 9456a18..bb11efd 100644 --- a/mini_program/farm-monitor-dashboard/src/utils/auth.js +++ b/mini_program/farm-monitor-dashboard/src/utils/auth.js @@ -1,202 +1,110 @@ -// Token管理工具 +import { login as apiLogin, validateToken } from '@/services/authService' -// 获取token -export function getToken() { - return uni.getStorageSync('token') -} +// 认证工具类 +export const auth = { + // 设置认证token + setToken(token) { + localStorage.setItem('token', token) + console.log('Token已设置:', token.substring(0, 20) + '...') + }, -// 设置token -export function setToken(token) { - uni.setStorageSync('token', token) -} + // 获取认证token + getToken() { + return localStorage.getItem('token') + }, -// 移除token -export function removeToken() { - uni.removeStorageSync('token') -} + // 清除认证token + clearToken() { + localStorage.removeItem('token') + console.log('Token已清除') + }, -// 检查是否已登录 -export function isLoggedIn() { - const token = getToken() - return !!token -} + // 检查是否已认证 + isAuthenticated() { + return !!this.getToken() + }, -// 获取用户信息 -export function getUserInfo() { - return uni.getStorageSync('userInfo') -} - -// 设置用户信息 -export function setUserInfo(userInfo) { - uni.setStorageSync('userInfo', userInfo) -} - -// 移除用户信息 -export function removeUserInfo() { - uni.removeStorageSync('userInfo') -} - -// 清除所有认证信息 -export function clearAuth() { - removeToken() - removeUserInfo() -} - -// 检查token是否过期(简单版本) -export function isTokenExpired() { - const token = getToken() - if (!token) return true - - try { - // 解析JWT token(如果使用JWT) - const payload = JSON.parse(atob(token.split('.')[1])) - const currentTime = Math.floor(Date.now() / 1000) - return payload.exp < currentTime - } catch (error) { - // 如果不是JWT token,使用简单的时间检查 - const tokenTime = uni.getStorageSync('tokenTime') - if (!tokenTime) return true + // 设置测试token(用于开发测试) + async setTestToken() { + // 首先检查是否已经有有效的token + const existingToken = this.getToken() + if (existingToken && existingToken.startsWith('eyJ')) { + console.log('使用现有JWT token') + return existingToken + } - const currentTime = Date.now() - const expiresIn = 24 * 60 * 60 * 1000 // 24小时 - return currentTime - tokenTime > expiresIn + try { + // 尝试使用测试账号登录获取真实token + console.log('开始API登录...') + const response = await apiLogin('admin', '123456') + console.log('API登录响应:', response) + + if (response && response.success && response.token) { + this.setToken(response.token) + console.log('成功获取真实token:', response.token.substring(0, 20) + '...') + return response.token + } else { + console.warn('API响应格式不正确:', response) + } + } catch (error) { + console.warn('无法通过API获取测试token,使用模拟token:', error.message) + } + + // 如果API登录失败,使用模拟token + const mockToken = 'mock-token-' + Date.now() + this.setToken(mockToken) + console.log('使用模拟token:', mockToken) + return mockToken + }, + + // 验证当前token是否有效 + async validateCurrentToken() { + const token = this.getToken() + if (!token) { + return false + } + + try { + await validateToken(token) + return true + } catch (error) { + console.warn('Token验证失败:', error.message) + this.clearToken() + return false + } + }, + + // 设置用户信息 + setUserInfo(userInfo) { + localStorage.setItem('userInfo', JSON.stringify(userInfo)) + }, + + // 获取用户信息 + getUserInfo() { + const userInfo = localStorage.getItem('userInfo') + return userInfo ? JSON.parse(userInfo) : null + }, + + // 清除用户信息 + clearUserInfo() { + localStorage.removeItem('userInfo') + }, + + // 登出 + logout() { + this.clearToken() + this.clearUserInfo() + console.log('用户已登出') + }, + + // 手动设置真实token(用于开发测试) + setRealToken() { + // 这是一个真实的JWT token,用于测试 + const realToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20iLCJpYXQiOjE3NTgxODM3NjEsImV4cCI6MTc1ODI3MDE2MX0.J3DD78bULP1pe5DMF2zbQEMFzeytV6uXgOuDIKOPww0' + this.setToken(realToken) + console.log('手动设置真实token') + return realToken } } -// 设置token时间 -export function setTokenTime() { - uni.setStorageSync('tokenTime', Date.now()) -} - -// 获取token时间 -export function getTokenTime() { - return uni.getStorageSync('tokenTime') -} - -// 登录状态检查 -export function checkAuth() { - if (!isLoggedIn()) { - uni.showModal({ - title: '提示', - content: '请先登录', - showCancel: false, - success: () => { - uni.reLaunch({ - url: '/pages/login/login' - }) - } - }) - return false - } - - if (isTokenExpired()) { - uni.showModal({ - title: '提示', - content: '登录已过期,请重新登录', - showCancel: false, - success: () => { - clearAuth() - uni.reLaunch({ - url: '/pages/login/login' - }) - } - }) - return false - } - - return true -} - -// 微信登录 -export function wxLogin() { - return new Promise((resolve, reject) => { - uni.login({ - provider: 'weixin', - success: (res) => { - if (res.code) { - resolve(res.code) - } else { - reject(new Error('微信登录失败')) - } - }, - fail: (error) => { - reject(error) - } - }) - }) -} - -// 获取微信用户信息 -export function wxGetUserInfo() { - return new Promise((resolve, reject) => { - uni.getUserInfo({ - provider: 'weixin', - success: (res) => { - resolve(res.userInfo) - }, - fail: (error) => { - reject(error) - } - }) - }) -} - -// 检查微信登录状态 -export function checkWxLogin() { - return new Promise((resolve, reject) => { - uni.checkSession({ - success: () => { - resolve(true) - }, - fail: () => { - resolve(false) - } - }) - }) -} - -// 权限检查(根据用户角色) -export function checkPermission(requiredRole) { - const userInfo = getUserInfo() - if (!userInfo || !userInfo.role) { - return false - } - - // 简单的权限检查逻辑 - const userRole = userInfo.role - const roleHierarchy = { - 'admin': 3, - 'manager': 2, - 'user': 1 - } - - return roleHierarchy[userRole] >= roleHierarchy[requiredRole] -} - -// 退出登录 -export function logout() { - clearAuth() - uni.reLaunch({ - url: '/pages/login/login' - }) -} - -export default { - getToken, - setToken, - removeToken, - isLoggedIn, - getUserInfo, - setUserInfo, - removeUserInfo, - clearAuth, - isTokenExpired, - setTokenTime, - getTokenTime, - checkAuth, - wxLogin, - wxGetUserInfo, - checkWxLogin, - checkPermission, - logout -} \ No newline at end of file +export default auth \ No newline at end of file diff --git a/mini_program/farm-monitor-dashboard/test-auth.html b/mini_program/farm-monitor-dashboard/test-auth.html new file mode 100644 index 0000000..1918f4e --- /dev/null +++ b/mini_program/farm-monitor-dashboard/test-auth.html @@ -0,0 +1,42 @@ + + + + 认证测试 + + +

认证测试页面

+ +
+ + + + diff --git a/mini_program/farm-monitor-dashboard/test-collar-api.js b/mini_program/farm-monitor-dashboard/test-collar-api.js new file mode 100644 index 0000000..54fba36 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/test-collar-api.js @@ -0,0 +1,150 @@ +// 测试智能项圈API调用 +const axios = require('axios') + +// 创建axios实例 +const api = axios.create({ + baseURL: 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 测试获取智能项圈列表 +async function testGetCollarDevices() { + try { + console.log('测试获取智能项圈设备列表...') + + const response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 10 + } + }) + + console.log('API响应状态:', response.status) + console.log('API响应数据:', JSON.stringify(response.data, null, 2)) + + if (response.data && response.data.data) { + console.log(`成功获取 ${response.data.data.length} 个项圈设备`) + + // 检查数据字段映射 + const firstDevice = response.data.data[0] + if (firstDevice) { + console.log('第一个设备的数据字段:') + console.log('- sn:', firstDevice.sn) + console.log('- deviceId:', firstDevice.deviceId) + console.log('- voltage:', firstDevice.voltage) + console.log('- temperature:', firstDevice.temperature) + console.log('- state:', firstDevice.state) + console.log('- bandge_status:', firstDevice.bandge_status) + console.log('- walk:', firstDevice.walk) + console.log('- y_steps:', firstDevice.y_steps) + console.log('- time:', firstDevice.time) + console.log('- uptime:', firstDevice.uptime) + + // 测试绑定状态判断 + const isBound = firstDevice.bandge_status === 1 || firstDevice.bandge_status === '1' || + firstDevice.state === 1 || firstDevice.state === '1' + console.log('- 绑定状态判断 (bandge_status优先):', isBound) + console.log('- 绑定状态来源:', firstDevice.bandge_status !== undefined ? 'bandge_status' : 'state') + } + } + + } catch (error) { + console.error('API调用失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 测试搜索功能 +async function testSearchCollarDevices() { + try { + console.log('\n测试搜索智能项圈设备...') + + const response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 10, + search: '2409' // 搜索包含2409的设备 + } + }) + + console.log('搜索API响应状态:', response.status) + console.log('搜索结果数量:', response.data?.data?.length || 0) + + } catch (error) { + console.error('搜索API调用失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 测试绑定状态判断 +async function testBindingStatus() { + try { + console.log('\n测试绑定状态判断...') + + const response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 20 + } + }) + + if (response.data && response.data.data) { + const devices = response.data.data + console.log(`分析 ${devices.length} 个设备的绑定状态:`) + + let boundCount = 0 + let unboundCount = 0 + + devices.forEach((device, index) => { + const isBound = device.bandge_status === 1 || device.bandge_status === '1' || + device.state === 1 || device.state === '1' + + if (isBound) { + boundCount++ + } else { + unboundCount++ + } + + console.log(`设备 ${index + 1}: ${device.sn || device.deviceId}`) + console.log(` - bandge_status: ${device.bandge_status}`) + console.log(` - state: ${device.state}`) + console.log(` - 绑定状态: ${isBound ? '已绑定' : '未绑定'}`) + console.log(` - 状态来源: ${device.bandge_status !== undefined ? 'bandge_status' : 'state'}`) + console.log('') + }) + + console.log(`统计结果:`) + console.log(`- 已绑定设备: ${boundCount} 个`) + console.log(`- 未绑定设备: ${unboundCount} 个`) + console.log(`- 总设备数: ${devices.length} 个`) + } + + } catch (error) { + console.error('绑定状态测试失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 运行测试 +async function runTests() { + console.log('开始测试智能项圈API...') + console.log('='.repeat(50)) + + await testGetCollarDevices() + await testSearchCollarDevices() + await testBindingStatus() + + console.log('\n测试完成!') +} + +// 如果直接运行此文件 +if (require.main === module) { + runTests().catch(console.error) +} + +module.exports = { + testGetCollarDevices, + testSearchCollarDevices, + testBindingStatus, + runTests +} diff --git a/mini_program/farm-monitor-dashboard/test-collar-pagination-search.js b/mini_program/farm-monitor-dashboard/test-collar-pagination-search.js new file mode 100644 index 0000000..b28e467 --- /dev/null +++ b/mini_program/farm-monitor-dashboard/test-collar-pagination-search.js @@ -0,0 +1,197 @@ +// 测试智能项圈分页和搜索功能 +const axios = require('axios') + +// 创建axios实例 +const api = axios.create({ + baseURL: 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 测试分页功能 +async function testPagination() { + try { + console.log('测试分页功能...') + console.log('='.repeat(40)) + + // 测试第一页 + console.log('\n1. 测试第一页 (page=1, limit=5)') + let response = await api.get('/api/smart-devices/collars', { + params: { page: 1, limit: 5 } + }) + + console.log('响应状态:', response.status) + console.log('数据数量:', response.data?.data?.length || 0) + console.log('分页信息:', response.data?.pagination) + + if (response.data?.pagination) { + const { current, pageSize, total, totalPages } = response.data.pagination + console.log(`第 ${current} 页,每页 ${pageSize} 条,共 ${total} 条,${totalPages} 页`) + + // 测试第二页 + if (totalPages > 1) { + console.log('\n2. 测试第二页 (page=2, limit=5)') + response = await api.get('/api/smart-devices/collars', { + params: { page: 2, limit: 5 } + }) + + console.log('响应状态:', response.status) + console.log('数据数量:', response.data?.data?.length || 0) + console.log('分页信息:', response.data?.pagination) + } + + // 测试最后一页 + if (totalPages > 2) { + console.log('\n3. 测试最后一页 (page=' + totalPages + ', limit=5)') + response = await api.get('/api/smart-devices/collars', { + params: { page: totalPages, limit: 5 } + }) + + console.log('响应状态:', response.status) + console.log('数据数量:', response.data?.data?.length || 0) + console.log('分页信息:', response.data?.pagination) + } + } + + } catch (error) { + console.error('分页测试失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 测试搜索功能 +async function testSearch() { + try { + console.log('\n\n测试搜索功能...') + console.log('='.repeat(40)) + + // 测试精确搜索 + console.log('\n1. 测试精确搜索项圈编号') + let response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 10, + search: '22012000108' // 使用图片中显示的项圈编号 + } + }) + + console.log('搜索响应状态:', response.status) + console.log('搜索结果数量:', response.data?.data?.length || 0) + console.log('搜索分页信息:', response.data?.pagination) + + if (response.data?.data?.length > 0) { + const device = response.data.data[0] + console.log('找到的设备信息:') + console.log('- 项圈编号:', device.sn || device.deviceId) + console.log('- 电量:', device.voltage) + console.log('- 温度:', device.temperature) + console.log('- 绑定状态:', device.bandge_status || device.state) + } + + // 测试模糊搜索 + console.log('\n2. 测试模糊搜索 (搜索包含"2201"的设备)') + response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 10, + search: '2201' + } + }) + + console.log('模糊搜索响应状态:', response.status) + console.log('模糊搜索结果数量:', response.data?.data?.length || 0) + console.log('模糊搜索分页信息:', response.data?.pagination) + + if (response.data?.data?.length > 0) { + console.log('匹配的设备编号:') + response.data.data.forEach((device, index) => { + console.log(` ${index + 1}. ${device.sn || device.deviceId}`) + }) + } + + // 测试无结果搜索 + console.log('\n3. 测试无结果搜索 (搜索不存在的编号)') + response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 10, + search: '99999999999' + } + }) + + console.log('无结果搜索响应状态:', response.status) + console.log('无结果搜索数量:', response.data?.data?.length || 0) + + } catch (error) { + console.error('搜索测试失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 测试搜索分页 +async function testSearchPagination() { + try { + console.log('\n\n测试搜索分页功能...') + console.log('='.repeat(40)) + + // 先搜索获取结果 + console.log('\n1. 搜索获取结果') + let response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 3, // 使用较小的分页大小便于测试 + search: '2201' + } + }) + + console.log('搜索响应状态:', response.status) + console.log('搜索结果数量:', response.data?.data?.length || 0) + console.log('搜索分页信息:', response.data?.pagination) + + if (response.data?.pagination && response.data.pagination.totalPages > 1) { + const { totalPages } = response.data.pagination + + // 测试搜索结果的第二页 + console.log('\n2. 测试搜索结果第二页') + response = await api.get('/api/smart-devices/collars', { + params: { + page: 2, + limit: 3, + search: '2201' + } + }) + + console.log('第二页响应状态:', response.status) + console.log('第二页结果数量:', response.data?.data?.length || 0) + console.log('第二页分页信息:', response.data?.pagination) + } + + } catch (error) { + console.error('搜索分页测试失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 运行所有测试 +async function runAllTests() { + console.log('开始测试智能项圈分页和搜索功能...') + console.log('='.repeat(60)) + + await testPagination() + await testSearch() + await testSearchPagination() + + console.log('\n\n所有测试完成!') + console.log('='.repeat(60)) +} + +// 如果直接运行此文件 +if (require.main === module) { + runAllTests().catch(console.error) +} + +module.exports = { + testPagination, + testSearch, + testSearchPagination, + runAllTests +} diff --git a/mini_program/farm-monitor-dashboard/test-pagination-fix.js b/mini_program/farm-monitor-dashboard/test-pagination-fix.js new file mode 100644 index 0000000..69ce69c --- /dev/null +++ b/mini_program/farm-monitor-dashboard/test-pagination-fix.js @@ -0,0 +1,146 @@ +// 测试分页修复 +const axios = require('axios') + +// 创建axios实例 +const api = axios.create({ + baseURL: 'http://localhost:5350', + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 测试分页数据 +async function testPaginationData() { + try { + console.log('测试分页数据修复...') + console.log('='.repeat(50)) + + // 测试第一页 + console.log('\n1. 测试第一页数据') + let response = await api.get('/api/smart-devices/collars', { + params: { page: 1, limit: 5 } + }) + + console.log('API响应状态:', response.status) + console.log('原始API响应分页信息:', response.data?.pagination) + console.log('响应数据结构:', { + hasData: !!response.data?.data, + dataLength: response.data?.data?.length || 0, + hasPagination: !!response.data?.pagination, + pagination: response.data?.pagination + }) + + if (response.data?.pagination) { + const { current, pageSize, total, totalPages } = response.data.pagination + console.log('分页信息验证:') + console.log('- current:', current, typeof current) + console.log('- pageSize:', pageSize, typeof pageSize) + console.log('- total:', total, typeof total) + console.log('- totalPages:', totalPages, typeof totalPages) + + // 计算分页显示信息 + const start = (current - 1) * pageSize + 1 + const end = Math.min(current * pageSize, total) + console.log('分页显示信息:', `第 ${start}-${end} 条,共 ${total} 条`) + + // 检查是否有NaN + if (isNaN(start) || isNaN(end) || isNaN(total)) { + console.error('❌ 发现NaN值!') + console.error('- start:', start, 'isNaN:', isNaN(start)) + console.error('- end:', end, 'isNaN:', isNaN(end)) + console.error('- total:', total, 'isNaN:', isNaN(total)) + } else { + console.log('✅ 分页计算正常,无NaN值') + } + } else { + console.log('❌ 缺少分页信息') + } + + // 测试第三页(模拟API返回page: 3的情况) + console.log('\n2. 测试第三页数据(模拟API返回page: 3)') + response = await api.get('/api/smart-devices/collars', { + params: { page: 3, limit: 5 } + }) + + console.log('第三页响应状态:', response.status) + console.log('原始API响应分页信息:', response.data?.pagination) + console.log('第三页分页信息:', response.data?.pagination) + + if (response.data?.pagination) { + const { current, pageSize, total } = response.data.pagination + console.log('字段映射验证:') + console.log('- API返回的page字段:', response.data?.pagination?.page || 'undefined') + console.log('- 映射后的current字段:', current) + console.log('- 是否匹配:', (response.data?.pagination?.page || 3) === current) + + const start = (current - 1) * pageSize + 1 + const end = Math.min(current * pageSize, total) + console.log('第三页显示信息:', `第 ${start}-${end} 条,共 ${total} 条`) + + // 验证分页高亮是否正确 + if (current === 3) { + console.log('✅ 分页高亮应该显示第3页') + } else { + console.log('❌ 分页高亮显示错误,应该是第3页,实际是第' + current + '页') + } + } + + } catch (error) { + console.error('测试失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 测试搜索分页 +async function testSearchPagination() { + try { + console.log('\n\n测试搜索分页...') + console.log('='.repeat(50)) + + // 测试搜索 + const response = await api.get('/api/smart-devices/collars', { + params: { + page: 1, + limit: 3, + search: '1501' + } + }) + + console.log('搜索响应状态:', response.status) + console.log('搜索结果数量:', response.data?.data?.length || 0) + console.log('搜索分页信息:', response.data?.pagination) + + if (response.data?.pagination) { + const { current, pageSize, total } = response.data.pagination + const start = (current - 1) * pageSize + 1 + const end = Math.min(current * pageSize, total) + console.log('搜索分页显示:', `搜索结果: 第 ${start}-${end} 条,共 ${total} 条`) + } + + } catch (error) { + console.error('搜索分页测试失败:', error.response?.status, error.response?.data || error.message) + } +} + +// 运行测试 +async function runTests() { + console.log('开始测试分页修复...') + console.log('='.repeat(60)) + + await testPaginationData() + await testSearchPagination() + + console.log('\n\n测试完成!') + console.log('='.repeat(60)) +} + +// 如果直接运行此文件 +if (require.main === module) { + runTests().catch(console.error) +} + +module.exports = { + testPaginationData, + testSearchPagination, + runTests +} diff --git a/mini_program/farm-monitor-dashboard/vue.config.js b/mini_program/farm-monitor-dashboard/vue.config.js index bc41d38..9b2e8f3 100644 --- a/mini_program/farm-monitor-dashboard/vue.config.js +++ b/mini_program/farm-monitor-dashboard/vue.config.js @@ -7,17 +7,23 @@ module.exports = defineConfig({ configureWebpack: { resolve: { alias: { - '@': require('path').resolve(__dirname, 'src') + '@': require('path').resolve(__dirname, 'src'), + // 强制uni-app使用CommonJS版本 + '@dcloudio/uni-app/dist/uni-app.es.js': require.resolve('@dcloudio/uni-app/dist/index.js') } } }, + // 配置public目录 + publicPath: '/', + assetsDir: 'static', + // 开发服务器配置 devServer: { port: 8080, proxy: { '/api': { - target: 'http://localhost:3000', + target: 'http://localhost:5350', changeOrigin: true, pathRewrite: { '^/api': '/api' @@ -30,7 +36,7 @@ module.exports = defineConfig({ css: { loaderOptions: { scss: { - additionalData: `@import "@/uni.scss";` + // 样式变量已在app.scss中导入 } } },