commit b962c9c716fe55f1261cea4c12252adba73aca96
Author: sexygoat <1538832180@qq.com>
Date: Sat Apr 11 14:42:14 2026 +0800
first commit
diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..7b274cb
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,9 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(git add:*)"
+ ],
+ "deny": [],
+ "ask": []
+ }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..71e2bf4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,94 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage/
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+
+# next.js build output
+.next
+
+# nuxt.js build output
+.nuxt
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# uni-app
+unpackage/
+dist/
+
+# VS Code
+.vscode/
+
+# IDE
+.idea/
+*.swp
+*.swo
+*~
+
+# OS
+.DS_Store
+Thumbs.db
\ No newline at end of file
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..a177e03
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,354 @@
+
+
+
+
+
+
diff --git a/api/index.js b/api/index.js
new file mode 100644
index 0000000..9846320
--- /dev/null
+++ b/api/index.js
@@ -0,0 +1,7 @@
+export { authApi } from './modules/auth.js';
+export { assetApi } from './modules/asset.js';
+export { deviceApi } from './modules/device.js';
+export { exchangeApi } from './modules/exchange.js';
+export { orderApi } from './modules/order.js';
+export { realnameApi } from './modules/realname.js';
+export { walletApi } from './modules/wallet.js';
\ No newline at end of file
diff --git a/api/modules/asset.js b/api/modules/asset.js
new file mode 100644
index 0000000..ae460d8
--- /dev/null
+++ b/api/modules/asset.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request.js';
+
+export const assetApi = {
+ getInfo(identifier) {
+ return request({
+ url: '/api/c/v1/asset/info',
+ method: 'GET',
+ data: { identifier }
+ });
+ },
+
+ getPackageHistory(identifier, page, page_size, params = {}) {
+ return request({
+ url: '/api/c/v1/asset/package-history',
+ method: 'GET',
+ data: { identifier, page, page_size, ...params }
+ });
+ },
+
+ getPackages(identifier) {
+ return request({
+ url: '/api/c/v1/asset/packages',
+ method: 'GET',
+ data: { identifier }
+ });
+ },
+
+ refresh(identifier) {
+ return request({
+ url: '/api/c/v1/asset/refresh',
+ method: 'POST',
+ data: { identifier }
+ });
+ }
+};
\ No newline at end of file
diff --git a/api/modules/auth.js b/api/modules/auth.js
new file mode 100644
index 0000000..a229aeb
--- /dev/null
+++ b/api/modules/auth.js
@@ -0,0 +1,50 @@
+import request from '@/utils/request.js';
+
+export const authApi = {
+ verifyAsset(identifier) {
+ return request({
+ url: '/api/c/v1/auth/verify-asset',
+ method: 'POST',
+ data: { identifier }
+ });
+ },
+
+ wechatLogin(asset_token, code) {
+ return request({
+ url: '/api/c/v1/auth/wechat-login',
+ method: 'POST',
+ data: { asset_token, code }
+ });
+ },
+
+ sendCode(phone, scene) {
+ return request({
+ url: '/api/c/v1/auth/send-code',
+ method: 'POST',
+ data: { phone, scene }
+ });
+ },
+
+ bindPhone(phone, code) {
+ return request({
+ url: '/api/c/v1/auth/bind-phone',
+ method: 'POST',
+ data: { phone, code }
+ });
+ },
+
+ changePhone(old_phone, old_code, new_phone, new_code) {
+ return request({
+ url: '/api/c/v1/auth/change-phone',
+ method: 'POST',
+ data: { old_phone, old_code, new_phone, new_code }
+ });
+ },
+
+ logout() {
+ return request({
+ url: '/api/c/v1/auth/logout',
+ method: 'POST'
+ });
+ }
+};
\ No newline at end of file
diff --git a/api/modules/device.js b/api/modules/device.js
new file mode 100644
index 0000000..8b3b702
--- /dev/null
+++ b/api/modules/device.js
@@ -0,0 +1,43 @@
+import request from '@/utils/request.js';
+
+export const deviceApi = {
+ getCards(identifier) {
+ return request({
+ url: '/api/c/v1/device/cards',
+ method: 'GET',
+ data: { identifier }
+ });
+ },
+
+ factoryReset(identifier) {
+ return request({
+ url: '/api/c/v1/device/factory-reset',
+ method: 'POST',
+ data: { identifier }
+ });
+ },
+
+ reboot(identifier) {
+ return request({
+ url: '/api/c/v1/device/reboot',
+ method: 'POST',
+ data: { identifier }
+ });
+ },
+
+ switchCard(identifier, target_iccid) {
+ return request({
+ url: '/api/c/v1/device/switch-card',
+ method: 'POST',
+ data: { identifier, target_iccid }
+ });
+ },
+
+ setWifi(identifier, ssid, password, enabled = true) {
+ return request({
+ url: '/api/c/v1/device/wifi',
+ method: 'POST',
+ data: { identifier, ssid, password, enabled }
+ });
+ }
+};
\ No newline at end of file
diff --git a/api/modules/exchange.js b/api/modules/exchange.js
new file mode 100644
index 0000000..362c57b
--- /dev/null
+++ b/api/modules/exchange.js
@@ -0,0 +1,19 @@
+import request from '@/utils/request.js';
+
+export const exchangeApi = {
+ getPending(identifier) {
+ return request({
+ url: '/api/c/v1/exchange/pending',
+ method: 'GET',
+ data: { identifier }
+ });
+ },
+
+ submitShippingInfo(id, recipient_name, recipient_phone, recipient_address) {
+ return request({
+ url: `/api/c/v1/exchange/${id}/shipping-info`,
+ method: 'POST',
+ data: { recipient_name, recipient_phone, recipient_address }
+ });
+ }
+};
\ No newline at end of file
diff --git a/api/modules/order.js b/api/modules/order.js
new file mode 100644
index 0000000..edbd9e9
--- /dev/null
+++ b/api/modules/order.js
@@ -0,0 +1,27 @@
+import request from '@/utils/request.js';
+import { APP_TYPE } from '@/utils/env.js';
+
+export const orderApi = {
+ getList(identifier, page, page_size, payment_status) {
+ return request({
+ url: '/api/c/v1/orders',
+ method: 'GET',
+ data: { identifier, page, page_size, payment_status }
+ });
+ },
+
+ getDetail(id) {
+ return request({
+ url: `/api/c/v1/orders/${id}`,
+ method: 'GET'
+ });
+ },
+
+ create(identifier, package_ids) {
+ return request({
+ url: '/api/c/v1/orders/create',
+ method: 'POST',
+ data: { identifier, package_ids, app_type: APP_TYPE }
+ });
+ }
+};
\ No newline at end of file
diff --git a/api/modules/realname.js b/api/modules/realname.js
new file mode 100644
index 0000000..299e825
--- /dev/null
+++ b/api/modules/realname.js
@@ -0,0 +1,11 @@
+import request from '@/utils/request.js';
+
+export const realnameApi = {
+ getLink(identifier, iccid) {
+ return request({
+ url: '/api/c/v1/realname/link',
+ method: 'GET',
+ data: { identifier, iccid }
+ });
+ }
+};
\ No newline at end of file
diff --git a/api/modules/wallet.js b/api/modules/wallet.js
new file mode 100644
index 0000000..502353c
--- /dev/null
+++ b/api/modules/wallet.js
@@ -0,0 +1,44 @@
+import request from '@/utils/request.js';
+import { APP_TYPE } from '@/utils/env.js';
+
+export const walletApi = {
+ getDetail(identifier) {
+ return request({
+ url: '/api/c/v1/wallet/detail',
+ method: 'GET',
+ data: { identifier }
+ });
+ },
+
+ recharge(identifier, amount, payment_method) {
+ return request({
+ url: '/api/c/v1/wallet/recharge',
+ method: 'POST',
+ data: { identifier, amount, payment_method, app_type: APP_TYPE }
+ });
+ },
+
+ rechargeCheck(identifier) {
+ return request({
+ url: '/api/c/v1/wallet/recharge-check',
+ method: 'GET',
+ data: { identifier }
+ });
+ },
+
+ getRecharges(identifier, page, page_size, status) {
+ return request({
+ url: '/api/c/v1/wallet/recharges',
+ method: 'GET',
+ data: { identifier, page, page_size, status }
+ });
+ },
+
+ getTransactions(identifier, page, page_size, params = {}) {
+ return request({
+ url: '/api/c/v1/wallet/transactions',
+ method: 'GET',
+ data: { identifier, page, page_size, ...params }
+ });
+ }
+};
\ No newline at end of file
diff --git a/components/DeviceStatusCard.vue b/components/DeviceStatusCard.vue
new file mode 100644
index 0000000..23714a8
--- /dev/null
+++ b/components/DeviceStatusCard.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ 当前卡: {{ deviceInfo.currentIccid }}
+
+
+
+ {{ isRealName ? "已实名" : "未实名" }}
+
+
+
+
+
+ 到期时间:{{ deviceInfo.expireDate }}
+
+
+ {{ deviceInfo.statusStr }}
+
+
+
+
+
+ 信号强度
+ {{ getSignalText(deviceInfo.rssi) }}
+
+
+ 设备电量
+ {{ deviceInfo.battery }} %
+
+
+ 连接数量
+ {{ deviceInfo.connCnt }} 台
+
+
+
+
+
+
+
+
diff --git a/components/FloatingButton.vue b/components/FloatingButton.vue
new file mode 100644
index 0000000..bf77fac
--- /dev/null
+++ b/components/FloatingButton.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+ 需要帮助?
+ 专属客服在线解答
+
+
+ 立即联系
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/FunctionCard.vue b/components/FunctionCard.vue
new file mode 100644
index 0000000..fc9da54
--- /dev/null
+++ b/components/FunctionCard.vue
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+ {{ realNameStatus || '实名认证' }}
+
+
+
+
+
+
+ 套餐订购
+
+
+
+
+
+ 我的订单
+
+
+
+
+
+ 后台管理
+
+
+
+
+
+ 切换运营商
+
+
+
+
+
+ 资产套餐历史
+
+
+
+
+
+ 绑定手机号
+
+
+
+
+
+ 更换手机号
+
+
+
+
+
+ 设备换货
+
+
+
+
+
+ 我的钱包
+
+
+
+
+
+ 重启设备
+
+
+
+
+
+ 恢复出厂
+
+
+
+
+
+ 退出登录
+
+
+
+
+
+
+
+
+
+
diff --git a/components/TrafficCard.vue b/components/TrafficCard.vue
new file mode 100644
index 0000000..2c13d87
--- /dev/null
+++ b/components/TrafficCard.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+ 已使用
+
+ {{ formatDataSize(deviceInfo.totalBytesCnt) }}
+ {{ isDevice ? 'GB' : 'MB' }}
+
+
+
+ 总流量
+
+ {{ formatDataSize(deviceInfo.flowSize) }}
+ {{ isDevice ? 'GB' : 'MB' }}
+
+
+
+ 剩余
+
+ {{ formatDataSize(deviceInfo.flowSize - deviceInfo.totalBytesCnt) }}
+ {{ isDevice ? 'GB' : 'MB' }}
+
+
+
+
+
+
+
+
+
diff --git a/components/UserInfoCard.vue b/components/UserInfoCard.vue
new file mode 100644
index 0000000..3a6bf74
--- /dev/null
+++ b/components/UserInfoCard.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+ {{ currentCardNo }}
+
+ 到期时间:{{ deviceInfo.expireDate }}
+
+
+ {{ onlineStatus }}
+
+
+
+
+
+
+
+
diff --git a/components/VoiceCard.vue b/components/VoiceCard.vue
new file mode 100644
index 0000000..b5262a0
--- /dev/null
+++ b/components/VoiceCard.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+ 总通话
+
+ {{ voiceStats.totalVoice }}
+ 分钟
+
+
+
+ 已使用
+
+ {{ voiceStats.usedVoice }}
+ 分钟
+
+
+
+ 剩余
+
+ {{ voiceStats.remainingVoice }}
+ 分钟
+
+
+
+
+
+
+
+
+
diff --git a/components/WhitelistCard.vue b/components/WhitelistCard.vue
new file mode 100644
index 0000000..4cefce7
--- /dev/null
+++ b/components/WhitelistCard.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+ 暂无白名单
+
+
+
+
+
+
+ {{ item.name }}
+
+ {{ getStateText(item.state) }}
+
+
+ {{ item.phone }}
+ {{ item.createTime }}
+
+
+
+
+
+
+
+
+
+
diff --git a/components/WifiCard.vue b/components/WifiCard.vue
new file mode 100644
index 0000000..fd303d2
--- /dev/null
+++ b/components/WifiCard.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ 网络名称
+ {{ deviceInfo.ssidName }}
+
+
+
+
+
+ 连接密码
+ {{ deviceInfo.ssidPwd }}
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/API.md b/docs/API.md
new file mode 100644
index 0000000..2d8b2d4
--- /dev/null
+++ b/docs/API.md
@@ -0,0 +1,1352 @@
+# BaseUrl: https://cmp-api.boss160.cn
+
+错误响应示例:
+{
+ "code": 1001,
+ "msg": "参数验证失败",
+ "data": {},
+ "timestamp": "2026-03-20T10:00:00Z"
+}
+
+# 2. 认证
+
+## 2.1 资产验证
+
+URL:
+POST /api/c/v1/auth/verify-asset
+
+请求说明:
+- 请求方式:POST
+- 认证方式:无需认证
+- Content-Type:application/json
+
+请求体参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求示例:
+{
+ "identifier": "1234567890"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "asset_token": "asset_token_example",
+ "expires_in": 300
+ }
+}
+
+字段说明:
+data:
+- asset_token:资产令牌(5分钟有效)
+- expires_in:过期时间(秒)
+
+
+
+## 2.2 公众号登录接口
+
+## 接口信息
+- **路径**:`POST /api/c/v1/auth/wechat-login`
+- **说明**:公众号登录(通过微信 OAuth code 登录)
+- **认证**:无需登录
+
+---
+
+## 请求参数
+
+### Body(application/json)
+
+```json
+{
+ "asset_token": "string",
+ "code": "string"
+}
+```
+
+---
+
+## 参数说明
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| asset_token | 是 | A1 返回的资产令牌 |
+| code | 是 | 微信 OAuth 授权码 | wxea8c599fe100ce8a 先临时用这个
+
+---
+
+## 返回结构
+
+```json
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-04-01T10:00:00Z",
+ "data": {
+ "is_new_user": false,
+ "need_bind_phone": false,
+ "token": "jwt_token"
+ }
+}
+```
+
+---
+
+## data 字段说明
+
+| 字段 | 说明 |
+|------|------|
+| is_new_user | 是否新用户 |
+| need_bind_phone | 是否需要绑定手机号 |
+| token | 登录后的 JWT Token |
+
+## 2.3 发送验证码
+
+URL:
+POST /api/c/v1/auth/send-code
+
+请求说明:
+- 请求方式:POST
+- 认证方式:无需认证
+- Content-Type:application/json
+
+请求体参数:
+- phone(string,必填)- 手机号(11位)
+- scene(string,必填)- 业务场景(bind_phone:绑定手机号, change_phone_old:换绑旧手机, change_phone_new:换绑新手机)
+
+请求示例:
+{
+ "phone": "13800138000",
+ "scene": "bind_phone"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "cooldown_seconds": 60
+ }
+}
+
+字段说明:
+data:
+- cooldown_seconds:冷却秒数
+
+
+
+## 2.4 绑定手机号
+
+URL:
+POST /api/c/v1/auth/bind-phone
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- phone(string,必填)- 手机号(11位)
+- code(string,必填)- 验证码(6位)
+
+请求示例:
+{
+ "phone": "13800138000",
+ "code": "123456"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "phone": "13800138000",
+ "bound_at": "2026-03-20T10:00:00Z"
+ }
+}
+
+字段说明:
+data:
+- phone:已绑定手机号
+- bound_at:绑定时间
+
+
+
+
+## 2.5 更换手机号
+
+URL:
+POST /api/c/v1/auth/change-phone
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- old_phone(string,必填)- 旧手机号(11位)
+- old_code(string,必填)- 旧手机号验证码(6位)
+- new_phone(string,必填)- 新手机号(11位)
+- new_code(string,必填)- 新手机号验证码(6位)
+
+请求示例:
+{
+ "old_phone": "13800138000",
+ "old_code": "123456",
+ "new_phone": "13900139000",
+ "new_code": "654321"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "phone": "13900139000",
+ "changed_at": "2026-03-20T10:00:00Z"
+ }
+}
+
+字段说明:
+data:
+- phone:换绑后手机号
+- changed_at:换绑时间
+
+
+
+## 2.6 退出登录
+
+URL:
+POST /api/c/v1/auth/logout
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+(无请求体)
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "success": true
+ }
+}
+
+字段说明:
+data:
+- success:是否成功
+
+
+url: /api/c/v1/asset/info
+请求地址的响应发生变化, 请根据变化来调整首页里面的数据 我有在响应后面加了注释
+然后到期时间: 拿的是 资产套餐历史 列表里面的 "status_name": "生效中",expires_at
+```json
+{
+ "code": 0,
+ "data": {
+ "asset_type": "device", // isDevice: true, 如果是device就是true
+ "asset_id": 1,
+ "identifier": "862639070804960", // 当前卡
+ "virtual_no": "862639070804960",
+ "status": 1, // 状态 到期时间右边那个
+ "real_name_status": 0, // 实名状态
+ "carrier_name": "", // 运营商
+ "generation": "1",
+ "wallet_balance": 0,
+ "current_package": "",
+ "package_total_mb": 0,
+ "package_used_mb": 0,
+ "package_remain_mb": 0,
+ "device_name": "WiFi1",
+ "imei": "862639070804960",
+ "device_model": "WM-2000",
+ "device_type": "WiFi",
+ "manufacturer": "华为",
+ "max_sim_slots": 4,
+ "bound_card_count": 1,
+ "cards": [
+ {
+ "card_id": 5,
+ "iccid": "89860441192590297661",
+ "msisdn": "13800138000",
+ "network_status": 0,
+ "real_name_status": 0,
+ "slot_position": 1,
+ "is_current": false
+ }
+ ],
+ "device_protect_status": "none",
+ "device_realtime": {
+ "gateway_msg": null,
+ "online_status": 1, // 在线状态(1:在线, 2:离线)
+ "battery_level": 100, // 设备电量
+ "status": 0,
+ "run_time": "527020",
+ "connect_time": "239077",
+ "rsrp": -78, // 根据这三个计算出网络信号
+ "rsrq": -9, // 根据这三个计算出网络信号
+ "rssi": "-47", // 根据这三个计算出网络信号
+ "sinr": 12,
+ "ssid": "MiFi-DA78", // WiFi名称
+ "wifi_enabled": true,
+ "wifi_password": "1234567890", // WiFi密码
+ "wan_ip": "10.99.164.211",
+ "lan_ip": "192.168.1.1", // 点击后台管理
+ "mac_address": "60:83:e2:01:da:78",
+ "daily_usage": "3321987788",
+ "dl_stats": "0",
+ "ul_stats": "0",
+ "limit_speed": 0,
+ "max_clients": 1, // 放到连接数里面 现在换成 client_number/max_clients
+ "client_number": 1, // 已连接数 现在换成 client_number/max_clients
+ "software_version": "LBF2AKAS01070_N20_8_ESIM_V001",
+ "sync_interval": 120,
+ "device_id": "862639070804960",
+ "imei": "862639070804960",
+ "imsi": "460068049567506"
+ }
+ },
+ "msg": "success",
+ "timestamp": "2026-03-30T09:21:25+08:00"
+}
+```
+
+
+# 3. 资产
+
+## 3.1 资产信息
+
+URL:
+GET /api/c/v1/asset/info
+
+Query 参数:
+identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+/api/c/v1/asset/info?identifier=1234567890
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "asset_id": 1,
+ "asset_type": "device",
+ "carrier_name": "中国移动",
+ "generation": "4G",
+ "identifier": "1234567890",
+ "real_name_status": 1,
+ "status": 1,
+ "virtual_no": "17000000000",
+ "wallet_balance": 1000
+ }
+}
+
+字段说明:
+data:
+- asset_id:资产ID
+- asset_type:资产类型(card:卡, device:设备)
+- carrier_name:运营商名称
+- generation:制式
+- identifier:资产标识符
+- real_name_status:实名状态(0:未实名, 1:已实名)
+- status:状态(0:禁用, 1:启用)
+- virtual_no:虚拟号
+- wallet_balance:钱包余额(分)
+
+
+## 3.2 资产套餐历史
+
+URL:
+GET /api/c/v1/asset/package-history
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- page(integer,必填)- 页码
+- page_size(integer,必填)- 每页数量
+- package_type(string,可选)- 套餐类型 (formal:正式套餐, addon:加油包)
+- status(integer,必填)- 套餐状态 (0:待生效, 1:生效中, 2:已用完, 3:已过期, 4:已失效)
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/asset/package-history?identifier=1234567890&page=1&page_size=10
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "items": [
+ {
+ "activated_at": "2026-03-01T00:00:00Z",
+ "created_at": "2026-03-01T00:00:00Z",
+ "data_limit_mb": 10240,
+ "data_usage_mb": 2048,
+ "expires_at": "2026-03-31T23:59:59Z",
+ "master_usage_id": null,
+ "package_id": 1001,
+ "package_name": "10GB月套餐",
+ "package_type": "formal",
+ "package_usage_id": 5001,
+ "priority": 1,
+ "status": 1,
+ "status_name": "生效中",
+ "usage_type": "single_card",
+ "virtual_limit_mb": 20480,
+ "virtual_ratio": 0.5,
+ "virtual_remain_mb": 16384,
+ "virtual_used_mb": 4096
+ }
+ ],
+ "page": 1,
+ "page_size": 10,
+ "total": 1
+ }
+}
+
+字段说明:
+data:
+- items:套餐历史列表
+- page:页码
+- page_size:每页数量
+- total:总数
+
+data.items[]:
+- activated_at:激活时间(待生效套餐为空)
+- created_at:创建时间
+- data_limit_mb:套餐真流量总量(MB)
+- data_usage_mb:已用真流量(MB)
+- expires_at:到期时间(待生效套餐为空)
+- master_usage_id:主套餐ID(加油包时有值)
+- package_id:套餐ID
+- package_name:套餐名称
+- package_type:套餐类型(formal 普通类型 / addon 加油包)
+- package_usage_id:套餐使用记录ID
+- priority:优先级
+- status:状态(0待生效 1生效中 2已用完 3已过期 4已失效)
+- status_name:状态名称
+- usage_type:使用类型(single_card/device)
+- virtual_limit_mb:套餐虚流量总量(MB),按virtual_ratio换算
+- virtual_ratio:虚流量比例(real/virtual)
+- virtual_remain_mb:剩余虚流量(MB),按virtual_ratio换算
+- virtual_used_mb:已用虚流量(MB),按virtual_ratio换算
+
+## 3.3 资产可购套餐列表
+
+URL:
+GET /api/c/v1/asset/packages
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/asset/packages?identifier=1234567890
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "packages": [
+ {
+ "cost_price": 1000,
+ "data_allowance": 10240,
+ "data_unit": "MB",
+ "description": "适用于日常上网使用",
+ "is_addon": false,
+ "package_id": 1001,
+ "package_name": "10GB月套餐",
+ "package_type": "formal",
+ "retail_price": 1500,
+ "validity_days": 30
+ }
+ ]
+ }
+}
+
+字段说明:
+data:
+- packages:套餐列表
+
+data.packages[]:
+- cost_price:成本价(分)
+- data_allowance:流量额度
+- data_unit:流量单位
+- description:套餐说明
+- is_addon:是否加油包
+- package_id:套餐ID
+- package_name:套餐名称
+- package_type:套餐类型(formal:正式套餐, addon:加油包)
+- retail_price:零售价(分)
+- validity_days:有效天数
+
+
+## 3.4 资产刷新
+
+URL:
+POST /api/c/v1/asset/refresh
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求示例:
+{
+ "identifier": "1234567890"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "accepted": true,
+ "cooldown_seconds": 60,
+ "refresh_type": "device"
+ }
+}
+
+字段说明:
+data:
+- accepted:是否已受理
+- cooldown_seconds:冷却秒数
+- refresh_type:刷新类型(card:卡, device:设备)
+
+
+# 4. 设备
+
+## 4.1 获取设备卡列表
+
+URL:
+GET /api/c/v1/device/cards
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/device/cards?identifier=1234567890
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "cards": [
+ {
+ "card_id": 1,
+ "carrier_name": "中国移动",
+ "iccid": "89860012345678901234",
+ "is_active": true,
+ "msisdn": "17000000000",
+ "network_status": "online",
+ "real_name_status": 1,
+ "slot_position": 1
+ }
+ ]
+ }
+}
+
+字段说明:
+data:
+- cards:设备卡列表
+
+data.cards[]:
+- card_id:卡ID
+- carrier_name:运营商名称
+- iccid:物联网卡ICCID
+- is_active:是否当前激活卡
+- msisdn:手机号
+- network_status:网络状态
+- real_name_status:实名状态(0:未实名, 1:已实名)
+- slot_position:插槽位置
+
+## 4.2 恢复出厂设置
+URL:
+POST /api/c/v1/device/factory-reset
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求示例:
+{
+ "identifier": "1234567890"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "accepted": true,
+ "request_id": "req_123456789"
+ }
+}
+
+字段说明:
+data:
+- accepted:是否已受理
+- request_id:请求ID
+
+## 4.3 设备重启
+
+URL:
+POST /api/c/v1/device/reboot
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求示例:
+{
+ "identifier": "1234567890"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "accepted": true,
+ "request_id": "req_123456789"
+ }
+}
+
+字段说明:
+data:
+- accepted:是否已受理
+- request_id:请求ID
+
+## 4.4 设备切卡
+
+URL:
+POST /api/c/v1/device/switch-card
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- target_iccid(string,必填)- 目标ICCID
+
+请求示例:
+{
+ "identifier": "1234567890",
+ "target_iccid": "89860012345678901234"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "accepted": true,
+ "target_iccid": "89860012345678901234"
+ }
+}
+
+字段说明:
+data:
+- accepted:是否已受理
+- target_iccid:目标ICCID
+
+
+## 4.5 设备WiFi配置
+
+URL:
+POST /api/c/v1/device/wifi
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- enabled(boolean,必填)- 是否启用WiFi
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- password(string,必填)- WiFi密码
+- ssid(string,必填)- WiFi名称
+
+请求示例:
+{
+ "enabled": true,
+ "identifier": "1234567890",
+ "password": "12345678",
+ "ssid": "MyWiFi"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "accepted": true,
+ "request_id": "req_123456789"
+ }
+}
+
+字段说明:
+data:
+- accepted:是否已受理
+- request_id:请求ID
+
+
+# 5. 换货
+
+## 5.1 提交收货信息
+
+URL:
+POST /api/c/v1/exchange/{id}/shipping-info
+
+Path 参数:
+- id(integer,必填)- 换货单ID
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- recipient_address(string,必填)- 收货地址
+- recipient_name(string,必填)- 收件人姓名
+- recipient_phone(string,必填)- 收件人电话
+
+请求示例:
+{
+ "recipient_address": "广东省深圳市南山区科技园1号",
+ "recipient_name": "张三",
+ "recipient_phone": "13800138000"
+}
+
+成功响应示例:
+(接口文档未定义成功响应示例,通常为 200/204,可根据后端实际返回补充)
+
+字段说明:
+请求体:
+- recipient_address:收货地址
+- recipient_name:收件人姓名
+- recipient_phone:收件人电话
+
+## 5.2 查询待处理换货单
+
+URL:
+GET /api/c/v1/exchange/pending
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(ICCID/虚拟号/IMEI/SN)
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/exchange/pending?identifier=1234567890
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "id": 1,
+ "exchange_no": "EX202603200001",
+ "exchange_reason": "设备故障",
+ "status": 1,
+ "status_text": "待填写信息",
+ "created_at": "2026-03-20T10:00:00Z"
+ }
+}
+
+字段说明:
+data:
+- id:换货单ID
+- exchange_no:换货单号
+- exchange_reason:换货原因
+- status:换货状态(1:待填写信息, 2:待发货, 3:已发货待确认, 4:已完成, 5:已取消)
+- status_text:换货状态文本
+- created_at:创建时间
+
+
+# 6. 订单
+
+## 6.1 订单列表
+
+URL:
+GET /api/c/v1/orders
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- payment_status(integer,选填)- 支付状态(0:待支付, 1:已支付, 2:已取消)
+- page(integer,必填)- 页码
+- page_size(integer,必填)- 每页数量
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/orders?identifier=1234567890&payment_status=1&page=1&page_size=10
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "items": [
+ {
+ "created_at": "2026-03-20T10:00:00Z",
+ "order_id": 1,
+ "order_no": "ORD202603200001",
+ "package_names": [
+ "10GB月套餐",
+ "5GB加油包"
+ ],
+ "payment_status": 1,
+ "total_amount": 2500
+ }
+ ],
+ "page": 1,
+ "page_size": 10,
+ "total": 1
+ }
+}
+
+字段说明:
+data:
+- items:订单列表
+- page:页码
+- page_size:每页数量
+- total:总数
+
+data.items[]:
+- created_at:创建时间
+- order_id:订单ID
+- order_no:订单号
+- package_names:套餐名称列表
+- payment_status:支付状态(0:待支付, 1:已支付, 2:已取消)
+- total_amount:订单总金额(分)
+
+## 6.2 订单详情
+
+URL:
+GET /api/c/v1/orders/{id}
+
+Path 参数:
+- id(integer,必填)- 订单ID
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/orders/1
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "completed_at": "2026-03-20T10:30:00Z",
+ "created_at": "2026-03-20T10:00:00Z",
+ "order_id": 1,
+ "order_no": "ORD202603200001",
+ "packages": [
+ {
+ "package_id": 1001,
+ "package_name": "10GB月套餐",
+ "package_type": "formal",
+ "price": 1500,
+ "quantity": 1
+ },
+ {
+ "package_id": 1002,
+ "package_name": "5GB加油包",
+ "package_type": "addon",
+ "price": 1000,
+ "quantity": 1
+ }
+ ],
+ "paid_at": "2026-03-20T10:05:00Z",
+ "payment_method": "wechat",
+ "payment_status": 1,
+ "total_amount": 2500
+ }
+}
+
+字段说明:
+data:
+- completed_at:完成时间
+- created_at:创建时间
+- order_id:订单ID
+- order_no:订单号
+- packages:订单套餐列表
+- paid_at:支付时间
+- payment_method:支付方式
+- payment_status:支付状态(0:待支付, 1:已支付, 2:已取消)
+- total_amount:订单总金额(分)
+
+data.packages[]:
+- package_id:套餐ID
+- package_name:套餐名称
+- package_type:套餐类型(formal:正式套餐, addon:加油包)
+- price:单价(分)
+- quantity:数量
+
+## 6.3 创建订单
+
+URL:
+POST /api/c/v1/orders/create
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- app_type(string,必填)- 应用类型(official_account:公众号, miniapp:小程序)
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- package_ids(array,必填)- 套餐ID列表
+
+请求示例:
+{
+ "app_type": "miniapp",
+ "identifier": "1234567890",
+ "package_ids": [1001, 1002]
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "linked_package_info": {
+ "force_recharge_amount": 500,
+ "package_names": [
+ "10GB月套餐",
+ "5GB加油包"
+ ],
+ "total_package_amount": 2500,
+ "wallet_credit": 300
+ },
+ "order": {
+ "created_at": "2026-03-20T10:00:00Z",
+ "order_id": 1,
+ "order_no": "ORD202603200001",
+ "payment_status": 0,
+ "total_amount": 2200
+ },
+ "order_type": "package",
+ "pay_config": {
+ "app_id": "wx1234567890",
+ "nonce_str": "randomstring",
+ "package": "prepay_id=wx201410272009395522657a690389285100",
+ "pay_sign": "SIGNATURE",
+ "sign_type": "RSA",
+ "timestamp": "1710928800"
+ },
+ "recharge": {
+ "amount": 500,
+ "auto_purchase_status": "enabled",
+ "recharge_id": 10,
+ "recharge_no": "RC202603200001",
+ "status": 0
+ }
+ }
+}
+
+字段说明:
+data:
+- linked_package_info:关联套餐信息
+- order:订单信息
+- order_type:订单类型(package:套餐订单, recharge:充值订单)
+- pay_config:支付配置
+- recharge:充值信息
+
+data.linked_package_info:
+- force_recharge_amount:强制充值金额(分)
+- package_names:套餐名称列表
+- total_package_amount:套餐总金额(分)
+- wallet_credit:钱包抵扣金额(分)
+
+data.order:
+- created_at:创建时间
+- order_id:订单ID
+- order_no:订单号
+- payment_status:支付状态(0:待支付, 1:已支付, 2:已取消)
+- total_amount:订单总金额(分)
+
+data.pay_config:
+- app_id:应用ID
+- nonce_str:随机字符串
+- package:预支付参数
+- pay_sign:支付签名
+- sign_type:签名类型
+- timestamp:时间戳
+
+data.recharge:
+- amount:充值金额(分)
+- auto_purchase_status:自动购包状态
+- recharge_id:充值ID
+- recharge_no:充值单号
+- status:状态(0:待支付, 1:已支付, 2:已关闭)
+
+
+# 7. 实名
+
+## 7.1 获取实名认证链接
+
+URL:
+GET /api/c/v1/realname/link
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- iccid(string,选填)- 物联网卡ICCID
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/realname/link?identifier=1234567890&iccid=89860012345678901234
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "card_info": {
+ "iccid": "89860012345678901234",
+ "msisdn": "17000000000",
+ "virtual_no": "17100000000"
+ },
+ "expire_at": "2026-03-20T10:30:00Z",
+ "realname_mode": "gateway",
+ "realname_url": "https://example.com/realname/verify"
+ }
+}
+
+字段说明:
+data:
+- card_info:卡片简要信息
+- expire_at:过期时间
+- realname_mode:实名模式(none:无需实名, template:模板实名, gateway:网关实名)
+- realname_url:实名链接
+
+data.card_info:
+- iccid:物联网卡ICCID
+- msisdn:手机号
+- virtual_no:虚拟号
+
+
+# 8. 钱包
+
+## 8.1 钱包详情
+
+URL:
+GET /api/c/v1/wallet/detail
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/wallet/detail?identifier=1234567890
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "balance": 10000,
+ "frozen_balance": 500,
+ "resource_id": 1,
+ "resource_type": "device",
+ "updated_at": "2026-03-20T10:00:00Z",
+ "wallet_id": 101
+ }
+}
+
+字段说明:
+data:
+- balance:可用余额(分)
+- frozen_balance:冻结余额(分)
+- resource_id:资源ID
+- resource_type:资源类型(iot_card:物联网卡, device:设备)
+- updated_at:更新时间
+- wallet_id:钱包ID
+
+## 8.2 创建充值订单
+
+URL:
+POST /api/c/v1/wallet/recharge
+
+请求说明:
+- 请求方式:POST
+- 认证方式:Bearer Token(JWT)
+- Content-Type:application/json
+
+请求体参数:
+- amount(integer,必填)- 充值金额(分)
+- app_type(string,必填)- 应用类型(official_account:公众号, miniapp:小程序)
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- payment_method(string,必填)- 支付方式(wechat:微信支付)
+
+请求示例:
+{
+ "amount": 1000,
+ "app_type": "miniapp",
+ "identifier": "1234567890",
+ "payment_method": "wechat"
+}
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "pay_config": {
+ "app_id": "wx1234567890",
+ "nonce_str": "randomstring",
+ "package": "prepay_id=wx201410272009395522657a690389285100",
+ "pay_sign": "SIGNATURE",
+ "sign_type": "RSA",
+ "timestamp": "1710928800"
+ },
+ "recharge": {
+ "amount": 1000,
+ "recharge_id": 1,
+ "recharge_no": "RC202603200001",
+ "status": 0
+ }
+ }
+}
+
+字段说明:
+data:
+- pay_config:支付配置
+- recharge:充值信息
+
+data.pay_config:
+- app_id:应用ID
+- nonce_str:随机字符串
+- package:预支付参数
+- pay_sign:支付签名
+- sign_type:签名类型
+- timestamp:时间戳
+
+data.recharge:
+- amount:充值金额(分)
+- recharge_id:充值ID
+- recharge_no:充值单号
+- status:状态(0:待支付, 1:已支付, 2:已关闭)
+
+
+## 8.3 充值前校验
+
+URL:
+GET /api/c/v1/wallet/recharge-check
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/wallet/recharge-check?identifier=1234567890
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "force_recharge_amount": 1000,
+ "max_amount": 100000,
+ "message": "当前资产需先充值后再进行相关操作",
+ "min_amount": 100,
+ "need_force_recharge": true,
+ "trigger_type": "low_balance"
+ }
+}
+
+字段说明:
+data:
+- force_recharge_amount:强制充值金额(分)
+- max_amount:最大充值金额(分)
+- message:提示信息
+- min_amount:最小充值金额(分)
+- need_force_recharge:是否需要强制充值
+- trigger_type:触发类型
+
+## 8.4 充值记录列表
+
+URL:
+GET /api/c/v1/wallet/recharges
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- status(integer,选填)- 充值状态(0:待支付, 1:已支付, 2:已关闭)
+- page(integer,必填)- 页码
+- page_size(integer,必填)- 每页数量
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/wallet/recharges?identifier=1234567890&status=1&page=1&page_size=10
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "items": [
+ {
+ "amount": 1000,
+ "auto_purchase_status": "enabled",
+ "created_at": "2026-03-20T10:00:00Z",
+ "payment_method": "wechat",
+ "recharge_id": 1,
+ "recharge_no": "RC202603200001",
+ "status": 1
+ }
+ ],
+ "page": 1,
+ "page_size": 10,
+ "total": 1
+ }
+}
+
+字段说明:
+data:
+- items:充值记录列表
+- page:页码
+- page_size:每页数量
+- total:总数
+
+data.items[]:
+- amount:充值金额(分)
+- auto_purchase_status:自动购包状态
+- created_at:创建时间
+- payment_method:支付方式
+- recharge_id:充值ID
+- recharge_no:充值单号
+- status:状态(0:待支付, 1:已支付, 2:已关闭)
+
+
+## 8.5 钱包流水列表
+
+URL:
+GET /api/c/v1/wallet/transactions
+
+Query 参数:
+- identifier(string,必填)- 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN)
+- transaction_type(string,选填)- 流水类型
+- start_time(string,选填)- 开始时间
+- end_time(string,选填)- 结束时间
+- page(integer,必填)- 页码
+- page_size(integer,必填)- 每页数量
+
+请求说明:
+- 请求方式:GET
+- 认证方式:Bearer Token(JWT)
+
+请求示例:
+GET /api/c/v1/wallet/transactions?identifier=1234567890&transaction_type=recharge&start_time=2026-03-01T00:00:00Z&end_time=2026-03-20T23:59:59Z&page=1&page_size=10
+
+成功响应示例:
+{
+ "code": 0,
+ "msg": "success",
+ "timestamp": "2026-03-20T10:00:00Z",
+ "data": {
+ "items": [
+ {
+ "amount": 1000,
+ "balance_after": 5000,
+ "created_at": "2026-03-20T10:00:00Z",
+ "remark": "钱包充值",
+ "transaction_id": 1,
+ "type": "recharge"
+ }
+ ],
+ "page": 1,
+ "page_size": 10,
+ "total": 1
+ }
+}
+
+字段说明:
+data:
+- items:流水列表
+- page:页码
+- page_size:每页数量
+- total:总数
+
+data.items[]:
+- amount:变动金额(分)
+- balance_after:变动后余额(分)
+- created_at:创建时间
+- remark:备注
+- transaction_id:流水ID
+- type:流水类型
diff --git a/docs/微信网页授权-OAuth2.md b/docs/微信网页授权-OAuth2.md
new file mode 100644
index 0000000..160ea4d
--- /dev/null
+++ b/docs/微信网页授权-OAuth2.md
@@ -0,0 +1,192 @@
+# 微信 H5 获取用户头像昵称(前端接入指南)
+
+## 一、目标
+在微信内打开 H5 页面,获取用户:
+- 昵称(nickname)
+- 头像(headimgurl)
+- openid
+
+---
+
+## 二、核心方案
+使用微信网页授权(OAuth2):
+
+- 必须使用:`snsapi_userinfo`
+- 才能获取头像 + 昵称
+
+---
+
+## 三、整体流程
+
+```
+用户进入页面
+ ↓
+判断是否有 code
+ ↓
+没有 → 跳微信授权
+ ↓
+用户同意授权
+ ↓
+微信回调(带 code)
+ ↓
+前端把 code 传给后端
+ ↓
+后端换 token + 获取用户信息
+ ↓
+返回前端
+```
+
+---
+
+## 四、前端代码(可直接用)
+
+### 1️⃣ 获取 code 并跳授权
+
+```js
+const getCode = () => {
+ const params = new URLSearchParams(window.location.search);
+ return params.get("code");
+};
+
+const redirectToWxAuth = () => {
+ const appid = "你的appid";
+ const redirectUri = encodeURIComponent(window.location.href);
+
+ const url = `https://open.weixin.qq.com/connect/oauth2/authorize
+ ?appid=${appid}
+ &redirect_uri=${redirectUri}
+ &response_type=code
+ &scope=snsapi_userinfo
+ &state=123#wechat_redirect`;
+
+ window.location.href = url;
+};
+
+// 执行
+const code = getCode();
+
+if (!code) {
+ redirectToWxAuth();
+}
+```
+
+---
+
+### 2️⃣ 拿 code 调后端
+
+```js
+const code = new URLSearchParams(location.search).get("code");
+
+if (code) {
+ fetch(`/api/wx/userinfo?code=${code}`)
+ .then(res => res.json())
+ .then(data => {
+ console.log("用户信息", data);
+ // data.nickname
+ // data.headimgurl
+ });
+}
+```
+
+---
+
+## 五、后端要做什么(你只需要对接)
+
+前端只需要知道:
+
+```http
+GET /api/wx/userinfo?code=xxx
+```
+
+后端返回:
+
+```json
+{
+ "openid": "xxx",
+ "nickname": "张三",
+ "headimgurl": "https://xxx.jpg"
+}
+```
+
+---
+
+## 六、重要配置(必须)
+
+### 1️⃣ 微信后台配置
+在公众号后台:
+
+- 设置 → 开发 → 网页授权域名
+- 填你的 H5 域名(必须)
+
+---
+
+### 2️⃣ 必须在微信内打开
+
+```js
+const isWechat = /micromessenger/i.test(navigator.userAgent);
+
+if (!isWechat) {
+ alert("请在微信中打开");
+}
+```
+
+---
+
+## 七、常见坑
+
+### ❗1. redirect_uri 报错
+原因:域名没配置
+
+---
+
+### ❗2. 一直循环授权
+原因:没有正确判断 code
+
+---
+
+### ❗3. 拿不到头像昵称
+原因:用了 `snsapi_base`
+
+---
+
+### ❗4. 页面刷新重复授权
+解决:拿到 code 后清掉
+
+```js
+window.history.replaceState({}, "", location.pathname);
+```
+
+---
+
+## 八、优化建议(推荐)
+
+### ✔️ 第一次
+- 用 `snsapi_userinfo`
+- 获取完整用户信息
+
+### ✔️ 后续
+- 用 `snsapi_base`
+- 用 openid 换你自己的用户数据
+
+---
+
+## 九、适用范围
+
+| 场景 | 是否可用 |
+|------|----------|
+| 微信内 H5 | ✅ |
+| 小程序 | ❌ |
+| 浏览器打开 | ❌ |
+
+---
+
+## 十、一句话总结
+
+👉 想拿头像昵称:
+
+必须走
+**微信授权 + snsapi_userinfo + 后端换数据**
+
+---
+
+## 完
\ No newline at end of file
diff --git a/docs/首页数据来源改动.md b/docs/首页数据来源改动.md
new file mode 100644
index 0000000..e69de29
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..40d9164
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..b2a139f
--- /dev/null
+++ b/main.js
@@ -0,0 +1,24 @@
+import App from './App'
+import uviewPlus from 'uview-plus'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+export function createApp() {
+ const app = createSSRApp(App)
+ app.use(uviewPlus)
+ return {
+ app
+ }
+}
+// #endif
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..149d1f0
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,100 @@
+{
+ "name" : "device-voice-h5",
+ "appid" : "__UNI__45F0251",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {},
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ /* ios打包配置 */
+ "ios" : {},
+ /* SDK配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "",
+ "setting" : {
+ "urlCheck" : false
+ },
+ "usingComponents" : true
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "3",
+ "h5" : {
+ "title" : "信息查询",
+ "template" : "index.html",
+ "router" : {
+ "mode" : "history"
+ },
+ "optimization" : {
+ "treeShaking" : {
+ "enable" : true
+ }
+ },
+ "publicPath" : "./",
+ "devServer" : {
+ "proxy" : {
+ "/kyhl-weixin-1.0" : {
+ "target" : "http://jhwl.whjhft.com",
+ "changeOrigin" : true,
+ "secure" : false
+ },
+ "/cm-api" : {
+ "target" : "http://report.whjhft.com",
+ "changeOrigin" : true,
+ "secure" : false
+ }
+ }
+ },
+ "sdkConfigs" : {}
+ }
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..be61193
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1621 @@
+{
+ "name": "device-voice-h5",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "clipboard": "^2.0.11",
+ "dayjs": "^1.11.19",
+ "uview-plus": "^3.6.29"
+ },
+ "devDependencies": {
+ "sass": "^1.63.2",
+ "sass-loader": "^10.4.1"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@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",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "25.0.3",
+ "resolved": "https://registry.npmmirror.com/@types/node/-/node-25.0.3.tgz",
+ "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmmirror.com/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-phases": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
+ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "peerDependencies": {
+ "acorn": "^8.14.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-formats/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.10",
+ "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.10.tgz",
+ "integrity": "sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001761",
+ "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz",
+ "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0",
+ "peer": true
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+ "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/clipboard": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
+ "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
+ "license": "MIT",
+ "dependencies": {
+ "good-listener": "^1.2.2",
+ "select": "^1.1.2",
+ "tiny-emitter": "^2.0.0"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.19",
+ "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.19.tgz",
+ "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
+ "license": "MIT"
+ },
+ "node_modules/delegate": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
+ "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.267",
+ "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
+ "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.4",
+ "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
+ "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
+ "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true
+ },
+ "node_modules/good-listener": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
+ "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
+ "license": "MIT",
+ "dependencies": {
+ "delegate": "^3.1.2"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.7.tgz",
+ "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/klona": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz",
+ "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.1.tgz",
+ "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.11.5"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/sass": {
+ "version": "1.63.2",
+ "resolved": "https://registry.npmmirror.com/sass/-/sass-1.63.2.tgz",
+ "integrity": "sha512-u56TU0AIFqMtauKl/OJ1AeFsXqRHkgO7nCWmHaDwfxDo9GUMSqBA4NEh6GMuh1CYVM7zuROYtZrHzPc2ixK+ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-loader": {
+ "version": "10.4.1",
+ "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-10.4.1.tgz",
+ "integrity": "sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "klona": "^2.0.4",
+ "loader-utils": "^2.0.0",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.0.0",
+ "semver": "^7.3.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "fibers": ">= 3.1.0",
+ "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+ "sass": "^1.3.0",
+ "webpack": "^4.36.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "fibers": {
+ "optional": true
+ },
+ "node-sass": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/select": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
+ "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.44.1",
+ "resolved": "https://registry.npmmirror.com/terser/-/terser-5.44.1.tgz",
+ "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.16",
+ "resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz",
+ "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/tiny-emitter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
+ "license": "MIT"
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/uview-plus": {
+ "version": "3.6.29",
+ "resolved": "https://registry.npmmirror.com/uview-plus/-/uview-plus-3.6.29.tgz",
+ "integrity": "sha512-zK522LR074rB4k3EARysmjsoOh+WjtFevIpvmV1wjVFqS3TT6brLZLd+gKa1ewxBsIgIPDTAabmnHWPsW9DWkQ==",
+ "dependencies": {
+ "clipboard": "^2.0.11",
+ "dayjs": "^1.11.3"
+ },
+ "engines": {
+ "HBuilderX": "^3.1.0",
+ "uni-app": "^4.66",
+ "uni-app-x": ""
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.4.tgz",
+ "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack": {
+ "version": "5.104.1",
+ "resolved": "https://registry.npmmirror.com/webpack/-/webpack-5.104.1.tgz",
+ "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.8",
+ "@types/json-schema": "^7.0.15",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.15.0",
+ "acorn-import-phases": "^1.0.3",
+ "browserslist": "^4.28.1",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.17.4",
+ "es-module-lexer": "^2.0.0",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.11",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.3.1",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^4.3.3",
+ "tapable": "^2.3.0",
+ "terser-webpack-plugin": "^5.3.16",
+ "watchpack": "^2.4.4",
+ "webpack-sources": "^3.3.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.3.3.tgz",
+ "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/webpack/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/webpack/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/webpack/node_modules/schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..ebb9f9b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,11 @@
+{
+ "devDependencies": {
+ "sass": "^1.63.2",
+ "sass-loader": "^10.4.1"
+ },
+ "dependencies": {
+ "clipboard": "^2.0.11",
+ "dayjs": "^1.11.19",
+ "uview-plus": "^3.6.29"
+ }
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..06ac055
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,91 @@
+{
+ "easycom": {
+ "autoscan": true,
+ // 注意一定要放在custom里,否则无效,https://ask.dcloud.net.cn/question/131175
+ "custom": {
+ "^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
+ "^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
+ "^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
+ }
+ },
+ "pages": [{
+ "path": "pages/login/login",
+ "style": {
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/index/index",
+ "style": {
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/package-order/package-order",
+ "style": {
+ "navigationBarTitleText": "套餐列表"
+ }
+ },
+ {
+ "path": "pages/switch/switch",
+ "style": {
+ "navigationBarTitleText": "切换运营商"
+ }
+ },
+ {
+ "path": "pages/asset-package-history/asset-package-history",
+ "style": {
+ "navigationBarTitleText": "资产套餐历史"
+ }
+ },
+ {
+ "path": "pages/order-list/order-list",
+ "style": {
+ "navigationBarTitleText": "我的订单"
+ }
+ },
+ {
+ "path": "pages/bind/bind",
+ "style": {
+ "navigationBarTitleText": "绑定手机号"
+ }
+ },
+ {
+ "path": "pages/change-phone/change-phone",
+ "style": {
+ "navigationBarTitleText": "更换手机号"
+ }
+ },
+ {
+ "path": "pages/device-exchange/device-exchange",
+ "style": {
+ "navigationBarTitleText": "设备换货"
+ }
+ },
+ {
+ "path": "pages/auth/auth",
+ "style": {
+ "navigationBarTitleText": "实名认证"
+ }
+ },
+ {
+ "path": "pages/my-wallet/my-wallet",
+ "style": {
+ "navigationBarTitleText": "我的钱包"
+ }
+ },
+ {
+ "path": "pages/error/error",
+ "style": {
+ "navigationStyle": "custom"
+ }
+ }
+ ],
+ "globalStyle": {
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "信息查询",
+ "navigationBarBackgroundColor": "#F8F8F8",
+ "backgroundColor": "#F8F8F8"
+ },
+ "uniIdRouter": {}
+}
\ No newline at end of file
diff --git a/pages/asset-package-history/asset-package-history.vue b/pages/asset-package-history/asset-package-history.vue
new file mode 100644
index 0000000..36418c5
--- /dev/null
+++ b/pages/asset-package-history/asset-package-history.vue
@@ -0,0 +1,240 @@
+
+
+
+
+ 📦
+ 暂无套餐记录
+ 当前账号下暂无套餐历史信息
+
+
+
+
+
+
+
+
+ 套餐类型
+ {{ item.package_type === 'formal' ? '普通套餐' : '加油包' }}
+
+
+ 使用类型
+ {{ item.usage_type === 'single_card' ? '单卡' : '设备' }}
+
+
+ 激活时间
+ {{ item.activated_at || '-' }}
+
+
+ 创建时间
+ {{ item.created_at }}
+
+
+ 到期时间
+ {{ item.expires_at || '-' }}
+
+
+ 优先级
+ {{ item.priority }}
+
+
+
+
+
+
+ 流量信息
+
+
+ 已用真流量
+ {{ formatMB(item.data_usage_mb) }}
+
+
+ 总量真流量
+ {{ formatMB(item.data_limit_mb) }}
+
+
+ 剩余虚流量
+ {{ formatMB(item.virtual_remain_mb) }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载中...
+ 没有更多了
+ 点击加载更多
+
+
+
+
+
+
+
diff --git a/pages/auth/auth.vue b/pages/auth/auth.vue
new file mode 100644
index 0000000..9c6b5da
--- /dev/null
+++ b/pages/auth/auth.vue
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+
+
+ ICCID: {{ item.iccid }}
+ 运营商: {{ getLogo(item.category).name }}
+
+
+
+
+ 已实名
+ 去实名
+
+
+
+
+
+ ✕
+
+ 实名认证
+ {{ currentModalIccid }}
+ 点击复制ICCID并跳转实名
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/bind/bind.vue b/pages/bind/bind.vue
new file mode 100644
index 0000000..ba61dff
--- /dev/null
+++ b/pages/bind/bind.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 绑定手机号
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/change-phone/change-phone.vue b/pages/change-phone/change-phone.vue
new file mode 100644
index 0000000..e0d5ca0
--- /dev/null
+++ b/pages/change-phone/change-phone.vue
@@ -0,0 +1,152 @@
+
+
+
+
+ 原手机号
+
+
+
+
+ 验证码
+
+
+
+
+
+
+
+
+ 新手机号
+
+
+
+
+ 验证码
+
+
+
+
+
+
+
+
+ 确认更换
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/device-exchange/device-exchange.vue b/pages/device-exchange/device-exchange.vue
new file mode 100644
index 0000000..5016a6c
--- /dev/null
+++ b/pages/device-exchange/device-exchange.vue
@@ -0,0 +1,217 @@
+
+
+
+ 🔄
+ 暂无换货记录
+ 当前账号下暂无设备换货记录
+
+
+
+
+
+
+
+ 换货原因
+ {{ exchangeData.exchange_reason }}
+
+
+ 申请时间
+ {{ formatTime(exchangeData.created_at) }}
+
+
+ 收件人
+ {{ exchangeData.recipient_name }}
+
+
+ 联系电话
+ {{ exchangeData.recipient_phone }}
+
+
+ 收货地址
+ {{ exchangeData.recipient_address }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/error/error.vue b/pages/error/error.vue
new file mode 100644
index 0000000..ced36b7
--- /dev/null
+++ b/pages/error/error.vue
@@ -0,0 +1,21 @@
+
+
+ 请在微信中打开...
+
+
+
+
+
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..476f50f
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,515 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/login/login.vue b/pages/login/login.vue
new file mode 100644
index 0000000..a6dbb33
--- /dev/null
+++ b/pages/login/login.vue
@@ -0,0 +1,116 @@
+
+
+
+
+ 登录
+
+
+
+
+
+ 立即登录
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/my-wallet/my-wallet.vue b/pages/my-wallet/my-wallet.vue
new file mode 100644
index 0000000..66434fb
--- /dev/null
+++ b/pages/my-wallet/my-wallet.vue
@@ -0,0 +1,397 @@
+
+
+
+
+ 账户余额(元)
+ {{ formatMoney(walletDetail.balance) }}
+
+
+
+
+
+
+
+
+
+
+
+ 📋
+ 暂无充值记录
+
+
+
+
+
+
+
+ 充值金额
+ +¥{{ formatMoney(item.amount) }}
+
+
+ 支付方式
+ {{ item.payment_method || '-' }}
+
+
+ 自动购包
+ {{ item.auto_purchase_status === '1' ? '已开启' : '未开启' }}
+
+
+ 创建时间
+ {{ item.created_at }}
+
+
+
+
+
+ 加载中...
+ — 没有更多了 —
+ 点击加载更多
+
+
+
+
+
+
+
+
+ 💰
+ 暂无钱包流水
+
+
+
+
+
+
+
+ 流水ID
+ {{ item.transaction_id }}
+
+
+ 变动后余额
+ ¥{{ formatMoney(item.balance_after) }}
+
+
+ 备注
+ {{ item.remark }}
+
+
+ 创建时间
+ {{ item.created_at }}
+
+
+
+
+
+ 加载中...
+ — 没有更多了 —
+ 点击加载更多
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/order-list/order-list.vue b/pages/order-list/order-list.vue
new file mode 100644
index 0000000..c345457
--- /dev/null
+++ b/pages/order-list/order-list.vue
@@ -0,0 +1,176 @@
+
+
+
+ 📋
+ 暂无订单
+ 当前账号下暂无订单信息
+
+
+
+
+
+
+
+ 下单时间
+ {{ item.created_at }}
+
+
+
+
+
+
+
+ {{ pkgName }}
+
+
+
+
+
+
+
+ 加载中...
+ 没有更多了
+ 点击加载更多
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/package-order/package-order.vue b/pages/package-order/package-order.vue
new file mode 100644
index 0000000..7a22c6e
--- /dev/null
+++ b/pages/package-order/package-order.vue
@@ -0,0 +1,131 @@
+
+
+
+ 📦
+ 暂无可购套餐
+ 当前资产暂无适用的套餐
+
+
+
+
+ ¥{{ formatMoney(item.retail_price) }}
+ {{ item.description }}
+
+ 流量: {{ formatData(item.data_allowance, item.data_unit) }}
+ 有效: {{ item.validity_days }}天
+
+
+ 立即订购
+
+
+
+
+
+ 套餐名称:{{ currentPackage?.package_name }}
+ 价格:¥{{ formatMoney(currentPackage?.retail_price) }}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/switch/switch.vue b/pages/switch/switch.vue
new file mode 100644
index 0000000..9acbb2f
--- /dev/null
+++ b/pages/switch/switch.vue
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+ {{ item.iccid }}
+
+ {{ getLogo(item.category).name }}
+
+
+
+
+ 当前使用
+
+
+ {{ item.real_name_status === 1 ? '已实名' : '未实名' }}
+
+
+
+
+
+
+
+ 切换此运营商
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/asset-package-history.png b/static/asset-package-history.png
new file mode 100644
index 0000000..f5e3b47
Binary files /dev/null and b/static/asset-package-history.png differ
diff --git a/static/authentication.png b/static/authentication.png
new file mode 100644
index 0000000..e003035
Binary files /dev/null and b/static/authentication.png differ
diff --git a/static/back.png b/static/back.png
new file mode 100644
index 0000000..bf8c8d3
Binary files /dev/null and b/static/back.png differ
diff --git a/static/bind-phone.png b/static/bind-phone.png
new file mode 100644
index 0000000..8585d5a
Binary files /dev/null and b/static/bind-phone.png differ
diff --git a/static/change-phone.png b/static/change-phone.png
new file mode 100644
index 0000000..fc62a4f
Binary files /dev/null and b/static/change-phone.png differ
diff --git a/static/change.png b/static/change.png
new file mode 100644
index 0000000..8781c25
Binary files /dev/null and b/static/change.png differ
diff --git a/static/link.png b/static/link.png
new file mode 100644
index 0000000..abaf5b1
Binary files /dev/null and b/static/link.png differ
diff --git a/static/login.png b/static/login.png
new file mode 100644
index 0000000..b78804b
Binary files /dev/null and b/static/login.png differ
diff --git a/static/order.png b/static/order.png
new file mode 100644
index 0000000..f8cb979
Binary files /dev/null and b/static/order.png differ
diff --git a/static/out.png b/static/out.png
new file mode 100644
index 0000000..97358e0
Binary files /dev/null and b/static/out.png differ
diff --git a/static/recover.png b/static/recover.png
new file mode 100644
index 0000000..5ba27be
Binary files /dev/null and b/static/recover.png differ
diff --git a/static/restart.png b/static/restart.png
new file mode 100644
index 0000000..39d9d94
Binary files /dev/null and b/static/restart.png differ
diff --git a/static/shop.png b/static/shop.png
new file mode 100644
index 0000000..21e83c4
Binary files /dev/null and b/static/shop.png differ
diff --git a/static/wallet.png b/static/wallet.png
new file mode 100644
index 0000000..0bd448f
Binary files /dev/null and b/static/wallet.png differ
diff --git a/store/asset.js b/store/asset.js
new file mode 100644
index 0000000..e21637e
--- /dev/null
+++ b/store/asset.js
@@ -0,0 +1,35 @@
+import { reactive, ref } from 'vue';
+
+const state = reactive({
+ assetInfo: null,
+ deviceRealtime: null,
+ currentPackage: null
+});
+
+export const useAssetStore = () => {
+ const setAssetInfo = (info) => {
+ state.assetInfo = info;
+ };
+
+ const setDeviceRealtime = (realtime) => {
+ state.deviceRealtime = realtime;
+ };
+
+ const setCurrentPackage = (pkg) => {
+ state.currentPackage = pkg;
+ };
+
+ const clearAsset = () => {
+ state.assetInfo = null;
+ state.deviceRealtime = null;
+ state.currentPackage = null;
+ };
+
+ return {
+ state,
+ setAssetInfo,
+ setDeviceRealtime,
+ setCurrentPackage,
+ clearAsset
+ };
+};
\ No newline at end of file
diff --git a/store/index.js b/store/index.js
new file mode 100644
index 0000000..ebe9f8d
--- /dev/null
+++ b/store/index.js
@@ -0,0 +1,2 @@
+export { useUserStore } from './user.js';
+export { useAssetStore } from './asset.js';
\ No newline at end of file
diff --git a/store/user.js b/store/user.js
new file mode 100644
index 0000000..4383206
--- /dev/null
+++ b/store/user.js
@@ -0,0 +1,50 @@
+import { reactive, ref } from 'vue';
+
+const state = reactive({
+ token: uni.getStorageSync('token') || '',
+ assetToken: '',
+ identifier: uni.getStorageSync('identifier') || '',
+ isDevice: false,
+ realNameStatus: 0
+});
+
+export const useUserStore = () => {
+ const setToken = (token) => {
+ state.token = token;
+ uni.setStorageSync('token', token);
+ };
+
+ const setAssetToken = (assetToken) => {
+ state.assetToken = assetToken;
+ };
+
+ const setIdentifier = (identifier) => {
+ state.identifier = identifier;
+ uni.setStorageSync('identifier', identifier);
+ };
+
+ const setIsDevice = (isDevice) => {
+ state.isDevice = isDevice;
+ };
+
+ const setRealNameStatus = (status) => {
+ state.realNameStatus = status;
+ };
+
+ const clearUser = () => {
+ state.token = '';
+ state.assetToken = '';
+ uni.removeStorageSync('token');
+ uni.removeStorageSync('identifier');
+ };
+
+ return {
+ state,
+ setToken,
+ setAssetToken,
+ setIdentifier,
+ setIsDevice,
+ setRealNameStatus,
+ clearUser
+ };
+};
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a4764b7
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "compilerOptions": {
+ "sourceMap": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ },
+ "lib": ["esnext", "dom"],
+ "types": [
+ "@dcloudio/types",
+ "uview-plus/types"
+ ]
+ },
+ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
+}
\ No newline at end of file
diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js
new file mode 100644
index 0000000..5fec4f3
--- /dev/null
+++ b/uni.promisify.adaptor.js
@@ -0,0 +1,13 @@
+uni.addInterceptor({
+ returnValue (res) {
+ if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+ return res;
+ }
+ return new Promise((resolve, reject) => {
+ res.then((res) => {
+ if (!res) return resolve(res)
+ return res[0] ? reject(res[0]) : resolve(res[1])
+ });
+ });
+ },
+});
\ No newline at end of file
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..c7f439e
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+@import 'uview-plus/theme.scss';
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;
diff --git a/utils/env.js b/utils/env.js
new file mode 100644
index 0000000..7149612
--- /dev/null
+++ b/utils/env.js
@@ -0,0 +1,5 @@
+export const BASE_URL = 'https://cmp-api.boss160.cn';
+
+export const APP_TYPE = 'miniapp';
+
+export const APP_ID = 'wxea8c599fe100ce8a';
\ No newline at end of file
diff --git a/utils/request.js b/utils/request.js
new file mode 100644
index 0000000..71de9b0
--- /dev/null
+++ b/utils/request.js
@@ -0,0 +1,57 @@
+import { BASE_URL } from './env.js';
+
+const request = (options) => {
+ return new Promise((resolve, reject) => {
+ const token = uni.getStorageSync('token') || '';
+
+ uni.request({
+ url: BASE_URL + options.url,
+ method: options.method || 'GET',
+ data: options.data || {},
+ header: {
+ 'Content-Type': 'application/json',
+ 'Authorization': token ? `Bearer ${token}` : '',
+ ...options.header
+ },
+ success: (res) => {
+ if (res.statusCode === 401) {
+ uni.removeStorageSync('token');
+ uni.removeStorageSync('identifier');
+ uni.showToast({
+ title: '登录已过期,请重新登录',
+ icon: 'none',
+ duration: 2000
+ });
+ setTimeout(() => {
+ uni.reLaunch({ url: '/pages/login/login' });
+ }, 2000);
+ reject(res.data);
+ return;
+ }
+
+ const { code, msg, data } = res.data;
+
+ if (code === 0 || code === 200) {
+ resolve(data);
+ } else {
+ uni.showToast({
+ title: msg || '请求失败',
+ icon: 'none',
+ duration: 2000
+ });
+ reject(res.data);
+ }
+ },
+ fail: (err) => {
+ uni.showToast({
+ title: '网络请求失败',
+ icon: 'none',
+ duration: 2000
+ });
+ reject(err);
+ }
+ });
+ });
+};
+
+export default request;
\ No newline at end of file