diff --git a/App.uvue b/App.uvue
index c394e95c..8bc9ebcf 100644
--- a/App.uvue
+++ b/App.uvue
@@ -9,6 +9,9 @@
diff --git a/layouts/admin/components/AdminAside.uvue b/layouts/admin/components/AdminAside.uvue
index a662125d..b2870425 100644
--- a/layouts/admin/components/AdminAside.uvue
+++ b/layouts/admin/components/AdminAside.uvue
@@ -21,16 +21,18 @@
-
diff --git a/layouts/admin/components/AdminSubsider.uvue b/layouts/admin/components/AdminSubsider.uvue
index 076e4f3b..968671b4 100644
--- a/layouts/admin/components/AdminSubsider.uvue
+++ b/layouts/admin/components/AdminSubsider.uvue
@@ -1,52 +1,160 @@
-
-
diff --git a/layouts/admin/components/AdminTagsView.uvue b/layouts/admin/components/AdminTagsView.uvue
index c272c6ad..f6e2468b 100644
--- a/layouts/admin/components/AdminTagsView.uvue
+++ b/layouts/admin/components/AdminTagsView.uvue
@@ -1,36 +1,122 @@
-
+
{{ t.title }}
-
+
×
-
+
+
+
+
+
+
diff --git a/layouts/admin/pages/HomeIndex.uvue b/layouts/admin/pages/HomeIndex.uvue
index 199d3d82..0b16eabe 100644
--- a/layouts/admin/pages/HomeIndex.uvue
+++ b/layouts/admin/pages/HomeIndex.uvue
@@ -1,74 +1,54 @@
-
-
-
-
-
- 91.1
-
- 昨日 2740
- 日环比 -96.67% ▼
-
-
-
+
+
+
-
-
-
- 224
-
- 昨日 136
- 日环比 64.7% ▲
-
-
-
+
-
-
-
- 4
-
- 昨日 8
- 日环比 -50% ▼
-
-
-
+
-
-
-
- 21
-
- 昨日 6
- 日环比 250% ▲
-
-
-
+
@@ -156,6 +136,7 @@ import { ref, computed, onMounted } from 'vue'
import AnalyticsComboChart from '@/components/analytics/AnalyticsComboChart.uvue'
import AnalyticsAreaChart from '@/components/analytics/AnalyticsAreaChart.uvue'
import AnalyticsPieChart from '@/components/analytics/AnalyticsPieChart.uvue'
+import KpiMiniCard from '@/pages/mall/admin/homePage/components/KpiMiniCard.uvue'
// Filter periods
const periods = [
@@ -244,103 +225,22 @@ const statsData = ref({
diff --git a/layouts/admin/router/adminComponentMap.uts b/layouts/admin/router/adminComponentMap.uts
index f9d1b48e..c22867c2 100644
--- a/layouts/admin/router/adminComponentMap.uts
+++ b/layouts/admin/router/adminComponentMap.uts
@@ -6,122 +6,25 @@
* value: 组件引用
*
* 注意:
- * 1. 所有组件必须静态导入,确保打包可分析
+ * 1. 组件已切换为 defineAsyncComponent 异步导入,优化 H5 环境下的加载性能与包体积
* 2. 组件路径使用 @ 别名
* 3. 占位组件统一使用 PlaceholderPage
*/
+import { defineAsyncComponent } from 'vue'
+
// 导入占位组件
import PlaceholderPage from '@/layouts/admin/components/PlaceholderPage.uvue'
// 导入首页(内部组件,不包含 AdminLayout)
import HomeIndex from '@/layouts/admin/pages/HomeIndex.uvue'
-// 导入用户模块(纯组件,不包含 AdminLayout)
-import UserStatistic from '@/pages/mall/admin/user/Statistic.uvue'
-import UserList from '@/pages/mall/admin/user/list.uvue'
-import UserLevel from '@/pages/mall/admin/user/level.uvue'
-import UserGroup from '@/pages/mall/admin/user/group.uvue'
-import UserLabel from '@/pages/mall/admin/user/label.uvue'
-import MemberConfig from '@/pages/mall/admin/user/MemberConfig.uvue'
-
-// 导入商品模块(纯组件,不包含 AdminLayout)
-import ProductStatistic from '@/pages/mall/admin/product/product-statistics/index.uvue'
-import ProductList from '@/pages/mall/admin/product/product-management/index.uvue'
-import ProductEdit from '@/pages/mall/admin/product/product-management/edit.uvue'
-import ProductMemberPrice from '@/pages/mall/admin/product/product-management/member-price.uvue'
-import ProductClassify from '@/pages/mall/admin/product/classify.uvue'
-import ProductReply from '@/pages/mall/admin/product/reply.uvue'
-import ProductAttr from '@/pages/mall/admin/product/attr.uvue'
-import ProductParam from '@/pages/mall/admin/product/param.uvue'
-import ProductLabel from '@/pages/mall/admin/product/label.uvue'
-import ProductProtection from '@/pages/mall/admin/product/protection.uvue'
-
-// 导入订单模块(纯组件,不包含 AdminLayout)
-import OrderList from '@/pages/mall/admin/order/list.uvue'
-import OrderStatistic from '@/pages/mall/admin/order/order-statistics/index.uvue'
-import OrderRefund from '@/pages/mall/admin/order/aftersales-order/index.uvue'
-import OrderCashier from '@/pages/mall/admin/order/cashier-order/index.uvue'
-import OrderVerify from '@/pages/mall/admin/order/write-off-records/index.uvue'
-import OrderConfig from '@/pages/mall/admin/order/order-configuration/index.uvue'
+// 用户、商品、订单模块已改为 defineAsyncComponent 异步加载,移除静态导入以优化 H5 加载性能
// 营销设置模块暂时使用 PlaceholderPage
// 避免循环依赖问题
-import CmsArticle from '@/pages/mall/admin/cms/article/list.uvue'
-import CmsCategory from '@/pages/mall/admin/cms/category/list.uvue'
-import MarketingCouponList from '@/pages/mall/admin/marketing/coupon/list.uvue'
-import MarketingCouponUser from '@/pages/mall/admin/marketing/coupon/user.uvue'
-import MarketingIntegralStatistic from '@/pages/mall/admin/marketing/integral/statistic.uvue'
-import MarketingIntegralProduct from '@/pages/mall/admin/marketing/integral/list.uvue'
-import MarketingIntegralOrder from '@/pages/mall/admin/marketing/integral/order.uvue'
-import MarketingIntegralRecord from '@/pages/mall/admin/marketing/integral/record.uvue'
-import MarketingIntegralConfig from '@/pages/mall/admin/marketing/integral/config.uvue'
-import MarketingLotteryList from '@/pages/mall/admin/marketing/lottery/list.uvue'
-import MarketingLotteryConfig from '@/pages/mall/admin/marketing/lottery/config.uvue'
-import MarketingCombinationProduct from '@/pages/mall/admin/marketing/combination/product.uvue'
-import MarketingCombinationList from '@/pages/mall/admin/marketing/combination/list.uvue'
-import MarketingCombinationCreate from '@/pages/mall/admin/marketing/combination/create.uvue'
-import MarketingSeckillList from '@/pages/mall/admin/marketing/seckill/list.uvue'
-import MarketingSeckillProduct from '@/pages/mall/admin/marketing/seckill/product.uvue'
-import MarketingSeckillConfig from '@/pages/mall/admin/marketing/seckill/config.uvue'
-// 导入财务模块(纯组件)
-import FinanceTransactionStats from '@/pages/mall/admin/finance/transaction_stats.uvue'
-import FinanceWithdrawal from '@/pages/mall/admin/finance/withdrawal.uvue'
-import FinanceInvoice from '@/pages/mall/admin/finance/invoice.uvue'
-import FinanceRecharge from '@/pages/mall/admin/finance/recharge.uvue'
-import FinanceCapitalFlow from '@/pages/mall/admin/finance/capital_flow.uvue'
-import FinanceBill from '@/pages/mall/admin/finance/bill.uvue'
-import FinanceCommission from '@/pages/mall/admin/finance/commission.uvue'
-import FinanceBalanceStats from '@/pages/mall/admin/finance/balance_stats.uvue'
-import FinanceBalanceRecord from '@/pages/mall/admin/finance/balance_record.uvue'
-
-// 导入客服模块
-import KefuList from '@/pages/mall/admin/kefu/list.uvue'
-import KefuWords from '@/pages/mall/admin/kefu/words.uvue'
-import KefuFeedback from '@/pages/mall/admin/kefu/feedback.uvue'
-import KefuAutoReply from '@/pages/mall/admin/kefu/auto_reply.uvue'
-import KefuConfig from '@/pages/mall/admin/kefu/config.uvue'
-
-// 导入装修模块
-import DecorationHome from '@/pages/mall/admin/decoration/home.uvue'
-import DecorationCategory from '@/pages/mall/admin/decoration/category.uvue'
-import DecorationUser from '@/pages/mall/admin/decoration/user.uvue'
-import DecorationData from '@/pages/mall/admin/decoration/data-config.uvue'
-import DecorationStyle from '@/pages/mall/admin/design/theme-style.uvue'
-import DecorationMaterial from '@/pages/mall/admin/design/material.uvue'
-import DecorationLink from '@/pages/mall/admin/design/link-management.uvue'
-
-// 导入直播管理
-import MarketingLiveRoom from '@/pages/mall/admin/marketing/live/room.uvue'
-import MarketingLiveProduct from '@/pages/mall/admin/marketing/live/product.uvue'
-import MarketingLiveAnchor from '@/pages/mall/admin/marketing/live/anchor.uvue'
-
-// 导入用户充值
-import MarketingRechargeQuota from '@/pages/mall/admin/marketing/recharge/quota.uvue'
-import MarketingRechargeConfig from '@/pages/mall/admin/marketing/recharge/config.uvue'
-
-// 导入每日签到
-import MarketingCheckinConfig from '@/pages/mall/admin/marketing/checkin/config.uvue'
-import MarketingCheckinReward from '@/pages/mall/admin/marketing/checkin/reward.uvue'
-
-// 导入新人礼
-import MarketingNewcomerGift from '@/pages/mall/admin/marketing/newcomer/index.uvue'
-
-// 导入付费会员
-import MarketingMemberType from '@/pages/mall/admin/marketing/member/type.uvue'
-import MarketingMemberRight from '@/pages/mall/admin/marketing/member/right.uvue'
-import MarketingMemberCard from '@/pages/mall/admin/marketing/member/card.uvue'
-import MarketingMemberRecord from '@/pages/mall/admin/marketing/member/record.uvue'
-import MarketingMemberConfig from '@/pages/mall/admin/marketing/member/config.uvue'
-
-// 导入维护模块
-import MaintainDevConfig from '@/pages/mall/admin/maintain/dev/config.uvue'
-
-// import StatisticIndex from '@/pages/mall/admin/statistic/index.uvue'
-// import SettingSystemConfig from '@/pages/mall/admin/setting/system/config.uvue'
-// import SettingSystemAdmin from '@/pages/mall/admin/setting/system/admin.uvue'
-// import SettingSystemRole from '@/pages/mall/admin/setting/system/role.uvue'
+// 营销、内容、财务、客服、装修等模块已改为 defineAsyncComponent 异步加载,移除静态导入以优化 H5 加载性能
/**
* 组件映射表
@@ -131,127 +34,146 @@ export const componentMap: Map = new Map([
['HomeIndex', HomeIndex],
// 用户模块
- ['UserStatistic', UserStatistic],
- ['UserList', UserList],
- ['UserLevel', UserLevel],
- ['UserGroup', UserGroup],
- ['UserLabel', UserLabel],
- ['UserMemberConfig', MemberConfig],
+ ['UserStatistic', defineAsyncComponent(() => import('@/pages/mall/admin/user/statistics/index.uvue'))],
+ ['UserList', defineAsyncComponent(() => import('@/pages/mall/admin/user/management/index.uvue'))],
+ ['UserLevel', defineAsyncComponent(() => import('@/pages/mall/admin/user/level/index.uvue'))],
+ ['UserGroup', defineAsyncComponent(() => import('@/pages/mall/admin/user/grouping/index.uvue'))],
+ ['UserLabel', defineAsyncComponent(() => import('@/pages/mall/admin/user/label/index.uvue'))],
+ ['UserMemberConfig', defineAsyncComponent(() => import('@/pages/mall/admin/user/configuration/index.uvue'))],
// 商品模块
- ['ProductStatistic', ProductStatistic],
- ['ProductList', ProductList],
- ['ProductEdit', ProductEdit],
- ['ProductMemberPrice', ProductMemberPrice],
- ['ProductClassify', ProductClassify],
- ['ProductReply', ProductReply],
- ['ProductAttr', ProductAttr],
- ['ProductParam', ProductParam],
- ['ProductLabel', ProductLabel],
- ['ProductProtection', ProductProtection],
+ ['ProductStatistic', defineAsyncComponent(() => import('@/pages/mall/admin/product/product-statistics/index.uvue'))],
+ ['ProductList', defineAsyncComponent(() => import('@/pages/mall/admin/product/product-management/index.uvue'))],
+ ['ProductEdit', defineAsyncComponent(() => import('@/pages/mall/admin/product/product-management/edit.uvue'))],
+ ['ProductMemberPrice', defineAsyncComponent(() => import('@/pages/mall/admin/product/product-management/member-price.uvue'))],
+ ['ProductClassify', defineAsyncComponent(() => import('@/pages/mall/admin/product/classification/index.uvue'))],
+ ['ProductReply', defineAsyncComponent(() => import('@/pages/mall/admin/product/reviews/index.uvue'))],
+ ['ProductAttr', defineAsyncComponent(() => import('@/pages/mall/admin/product/specifications/index.uvue'))],
+ ['ProductParam', defineAsyncComponent(() => import('@/pages/mall/admin/product/parameters/index.uvue'))],
+ ['ProductLabel', defineAsyncComponent(() => import('@/pages/mall/admin/product/labels/index.uvue'))],
+ ['ProductProtection', defineAsyncComponent(() => import('@/pages/mall/admin/product/protection/index.uvue'))],
// 订单模块
- ['OrderList', OrderList],
- ['OrderStatistic', OrderStatistic],
- ['OrderRefund', OrderRefund],
- ['OrderCashier', OrderCashier],
- ['OrderVerify', OrderVerify],
- ['OrderConfig', OrderConfig],
+ ['OrderList', defineAsyncComponent(() => import('@/pages/mall/admin/order/list.uvue'))],
+ ['OrderStatistic', defineAsyncComponent(() => import('@/pages/mall/admin/order/order-statistics/index.uvue'))],
+ ['OrderRefund', defineAsyncComponent(() => import('@/pages/mall/admin/order/aftersales-order/index.uvue'))],
+ ['OrderCashier', defineAsyncComponent(() => import('@/pages/mall/admin/order/cashier-order/index.uvue'))],
+ ['OrderVerify', defineAsyncComponent(() => import('@/pages/mall/admin/order/write-off-records/index.uvue'))],
+ ['OrderConfig', defineAsyncComponent(() => import('@/pages/mall/admin/order/order-configuration/index.uvue'))],
- // 营销模块
+ // 营销模块已改为异步加载
// 1. 优惠券
- ['MarketingCouponList', MarketingCouponList],
- ['MarketingCouponUser', MarketingCouponUser],
+ ['MarketingCouponList', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/coupon/list.uvue'))],
+ ['MarketingCouponUser', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/coupon/user.uvue'))],
// 2. 积分管理
- ['MarketingIntegralStatistic', MarketingIntegralStatistic],
- ['MarketingIntegralProduct', MarketingIntegralProduct],
- ['MarketingIntegralOrder', MarketingIntegralOrder],
- ['MarketingIntegralRecord', MarketingIntegralRecord],
- ['MarketingIntegralConfig', MarketingIntegralConfig],
+ ['MarketingIntegralStatistic', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/integral/statistic.uvue'))],
+ ['MarketingIntegralProduct', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/integral/list.uvue'))],
+ ['MarketingIntegralOrder', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/integral/order.uvue'))],
+ ['MarketingIntegralRecord', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/integral/record.uvue'))],
+ ['MarketingIntegralConfig', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/integral/config.uvue'))],
// 3. 抽奖管理
- ['MarketingLotteryList', MarketingLotteryList],
- ['MarketingLotteryConfig', MarketingLotteryConfig],
+ ['MarketingLotteryList', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/lottery/list.uvue'))],
+ ['MarketingLotteryConfig', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/lottery/config.uvue'))],
// 4. 砍价管理
['MarketingBargainProduct', PlaceholderPage],
['MarketingBargainList', PlaceholderPage],
// 5. 拼团管理
- ['MarketingCombinationProduct', MarketingCombinationProduct],
- ['MarketingCombinationList', MarketingCombinationList],
- ['MarketingCombinationCreate', MarketingCombinationCreate],
+ ['MarketingCombinationProduct', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/combination/product.uvue'))],
+ ['MarketingCombinationList', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/combination/list.uvue'))],
+ ['MarketingCombinationCreate', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/combination/create.uvue'))],
// 6. 秒杀管理
- ['MarketingSeckillList', MarketingSeckillList],
- ['MarketingSeckillProduct', MarketingSeckillProduct],
- ['MarketingSeckillConfig', MarketingSeckillConfig],
+ ['MarketingSeckillList', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/seckill/list.uvue'))],
+ ['MarketingSeckillProduct', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/seckill/product.uvue'))],
+ ['MarketingSeckillConfig', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/seckill/config.uvue'))],
// 7. 付费会员
- ['MarketingMemberType', MarketingMemberType],
- ['MarketingMemberRight', MarketingMemberRight],
- ['MarketingMemberCard', MarketingMemberCard],
- ['MarketingMemberRecord', MarketingMemberRecord],
- ['MarketingMemberConfig', MarketingMemberConfig],
+ ['MarketingMemberType', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/member/type.uvue'))],
+ ['MarketingMemberRight', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/member/right.uvue'))],
+ ['MarketingMemberCard', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/member/card.uvue'))],
+ ['MarketingMemberRecord', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/member/record.uvue'))],
+ ['MarketingMemberConfig', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/member/config.uvue'))],
// 8. 直播管理
- ['MarketingLiveRoom', MarketingLiveRoom],
- ['MarketingLiveProduct', MarketingLiveProduct],
- ['MarketingLiveAnchor', MarketingLiveAnchor],
+ ['MarketingLiveRoom', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/live/room.uvue'))],
+ ['MarketingLiveProduct', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/live/product.uvue'))],
+ ['MarketingLiveAnchor', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/live/anchor.uvue'))],
// 9. 用户充值
- ['MarketingRechargeQuota', MarketingRechargeQuota],
- ['MarketingRechargeConfig', MarketingRechargeConfig],
+ ['MarketingRechargeQuota', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/recharge/quota.uvue'))],
+ ['MarketingRechargeConfig', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/recharge/config.uvue'))],
// 10. 每日签到
- ['MarketingCheckinConfig', MarketingCheckinConfig],
- ['MarketingCheckinReward', MarketingCheckinReward],
+ ['MarketingCheckinConfig', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/checkin/config.uvue'))],
+ ['MarketingCheckinReward', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/checkin/reward.uvue'))],
// 11. 渠道码 & 新人礼
['MarketingChannelList', PlaceholderPage],
- ['MarketingNewcomerGift', MarketingNewcomerGift],
+ ['MarketingNewcomerGift', defineAsyncComponent(() => import('@/pages/mall/admin/marketing/newcomer/index.uvue'))],
// 内容模块
- ['CmsArticle', CmsArticle],
- ['CmsCategory', CmsCategory],
+ ['CmsArticle', defineAsyncComponent(() => import('@/pages/mall/admin/cms/article/list.uvue'))],
+ ['CmsCategory', defineAsyncComponent(() => import('@/pages/mall/admin/cms/category/list.uvue'))],
// 财务模块
- ['FinanceTransactionStats', FinanceTransactionStats],
- ['FinanceWithdrawal', FinanceWithdrawal],
- ['FinanceInvoice', FinanceInvoice],
- ['FinanceRecharge', FinanceRecharge],
- ['FinanceCapitalFlow', FinanceCapitalFlow],
- ['FinanceBill', FinanceBill],
- ['FinanceCommission', FinanceCommission],
- ['FinanceBalanceStats', FinanceBalanceStats],
- ['FinanceBalanceRecord', FinanceBalanceRecord],
+ ['FinanceTransactionStats', defineAsyncComponent(() => import('@/pages/mall/admin/finance/transaction_stats.uvue'))],
+ ['FinanceWithdrawal', defineAsyncComponent(() => import('@/pages/mall/admin/finance/withdrawal.uvue'))],
+ ['FinanceInvoice', defineAsyncComponent(() => import('@/pages/mall/admin/finance/invoice.uvue'))],
+ ['FinanceRecharge', defineAsyncComponent(() => import('@/pages/mall/admin/finance/recharge.uvue'))],
+ ['FinanceCapitalFlow', defineAsyncComponent(() => import('@/pages/mall/admin/finance/capital_flow.uvue'))],
+ ['FinanceBill', defineAsyncComponent(() => import('@/pages/mall/admin/finance/bill.uvue'))],
+ ['FinanceCommission', defineAsyncComponent(() => import('@/pages/mall/admin/finance/commission.uvue'))],
+ ['FinanceBalanceStats', defineAsyncComponent(() => import('@/pages/mall/admin/finance/balance_stats.uvue'))],
+ ['FinanceBalanceRecord', defineAsyncComponent(() => import('@/pages/mall/admin/finance/balance_record.uvue'))],
// 数据模块 - 暂时使用占位组件
['StatisticIndex', PlaceholderPage],
- // 设置模块 - 暂时使用占位组件
- ['SettingSystemConfig', PlaceholderPage],
- ['SettingSystemAdmin', PlaceholderPage],
- ['SettingSystemRole', PlaceholderPage],
+ // 设置模块
+ ['SettingSystemConfig', defineAsyncComponent(() => import('@/pages/mall/admin/setting/system/config.uvue'))],
+ ['SettingMessage', defineAsyncComponent(() => import('@/pages/mall/admin/setting/message.uvue'))],
+ ['SettingAgreement', defineAsyncComponent(() => import('@/pages/mall/admin/setting/agreement.uvue'))],
+ ['SettingTicket', defineAsyncComponent(() => import('@/pages/mall/admin/setting/ticket.uvue'))],
+ ['SettingAuthRole', defineAsyncComponent(() => import('@/pages/mall/admin/setting/auth/role.uvue'))],
+ ['SettingAuthAdmin', defineAsyncComponent(() => import('@/pages/mall/admin/setting/auth/admin.uvue'))],
+ ['SettingAuthPermission', defineAsyncComponent(() => import('@/pages/mall/admin/setting/auth/permission.uvue'))],
+ ['SettingDeliveryStaff', defineAsyncComponent(() => import('@/pages/mall/admin/setting/delivery/staff.uvue'))],
+ ['SettingDeliveryStation', defineAsyncComponent(() => import('@/pages/mall/admin/setting/delivery/station.uvue'))],
+ ['SettingDeliveryTemplate', defineAsyncComponent(() => import('@/pages/mall/admin/setting/delivery/template.uvue'))],
+ ['SettingInterfaceOnepassConfig', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/onepass/config.uvue'))],
+ ['SettingInterfaceOnepassIndex', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/onepass/index.uvue'))],
+ ['SettingInterfaceStorage', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/storage.uvue'))],
+ ['SettingInterfaceCollect', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/collect.uvue'))],
+ ['SettingInterfaceLogistics', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/logistics.uvue'))],
+ ['SettingInterfaceESheet', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/e-sheet.uvue'))],
+ ['SettingInterfaceSms', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/sms.uvue'))],
+ ['SettingInterfacePayment', defineAsyncComponent(() => import('@/pages/mall/admin/setting/interface/payment.uvue'))],
// 分销模块
['DistributionStatistic', PlaceholderPage],
- ['DistributionList', PlaceholderPage],
- ['DistributionConfig', PlaceholderPage],
+ ['DistributionPromoter', defineAsyncComponent(() => import('@/pages/mall/admin/distribution/promoter/index.uvue'))],
+ ['DistributionLevel', defineAsyncComponent(() => import('@/pages/mall/admin/distribution/level/index.uvue'))],
+ ['DistributionSetting', defineAsyncComponent(() => import('@/pages/mall/admin/distribution/setting/index.uvue'))],
+ ['DivisionList', defineAsyncComponent(() => import('@/pages/mall/admin/distribution/division/list.uvue'))],
+ ['DivisionAgent', defineAsyncComponent(() => import('@/pages/mall/admin/distribution/division/agent.uvue'))],
+ ['DivisionApply', defineAsyncComponent(() => import('@/pages/mall/admin/distribution/division/apply.uvue'))],
// 客服模块
- ['KefuList', KefuList],
- ['KefuWords', KefuWords],
- ['KefuFeedback', KefuFeedback],
- ['KefuAutoReply', KefuAutoReply],
- ['KefuConfig', KefuConfig],
+ ['KefuList', defineAsyncComponent(() => import('@/pages/mall/admin/kefu/list.uvue'))],
+ ['KefuWords', defineAsyncComponent(() => import('@/pages/mall/admin/kefu/words.uvue'))],
+ ['KefuFeedback', defineAsyncComponent(() => import('@/pages/mall/admin/kefu/feedback.uvue'))],
+ ['KefuAutoReply', defineAsyncComponent(() => import('@/pages/mall/admin/kefu/auto_reply.uvue'))],
+ ['KefuConfig', defineAsyncComponent(() => import('@/pages/mall/admin/kefu/config.uvue'))],
// 装修模块
- ['DecorationHome', DecorationHome],
- ['DecorationCategory', DecorationCategory],
- ['DecorationUser', DecorationUser],
- ['DecorationData', DecorationData],
- ['DecorationStyle', DecorationStyle],
- ['DecorationMaterial', DecorationMaterial],
- ['DecorationLink', DecorationLink],
+ ['DecorationHome', defineAsyncComponent(() => import('@/pages/mall/admin/decoration/home.uvue'))],
+ ['DecorationCategory', defineAsyncComponent(() => import('@/pages/mall/admin/decoration/category.uvue'))],
+ ['DecorationUser', defineAsyncComponent(() => import('@/pages/mall/admin/decoration/user.uvue'))],
+ ['DecorationData', defineAsyncComponent(() => import('@/pages/mall/admin/decoration/data-config.uvue'))],
+ ['DecorationStyle', defineAsyncComponent(() => import('@/pages/mall/admin/design/theme-style.uvue'))],
+ ['DecorationMaterial', defineAsyncComponent(() => import('@/pages/mall/admin/design/material.uvue'))],
+ ['DecorationLink', defineAsyncComponent(() => import('@/pages/mall/admin/design/link-management.uvue'))],
// 应用模块
['AppStatistic', PlaceholderPage],
['AppList', PlaceholderPage],
// 维护模块
- ['MaintainDevConfig', MaintainDevConfig],
+ ['MaintainDevConfig', defineAsyncComponent(() => import('@/pages/mall/admin/maintain/dev/config.uvue'))],
['MaintainDevData', PlaceholderPage],
['MaintainDevTask', PlaceholderPage],
['MaintainDevAuth', PlaceholderPage],
diff --git a/layouts/admin/router/adminRoutes.uts b/layouts/admin/router/adminRoutes.uts
index c9014968..ab48e721 100644
--- a/layouts/admin/router/adminRoutes.uts
+++ b/layouts/admin/router/adminRoutes.uts
@@ -69,7 +69,7 @@ export const topMenus: TopMenu[] = [
id: 'user',
title: '用户',
icon: 'user',
- path: '/pages/mall/admin/user/list',
+ path: '/pages/mall/admin/user/management/index',
order: 2,
groups: [
{ id: 'user-manage', title: '', order: 1 }
@@ -92,7 +92,7 @@ export const topMenus: TopMenu[] = [
path: '/pages/mall/admin/product/statistic',
order: 4,
groups: [
- { id: 'product-manage', title: '商品管理', order: 1 }
+ { id: 'product-manage', title: '', order: 1 }
]
},
{
@@ -156,7 +156,7 @@ export const topMenus: TopMenu[] = [
path: '/pages/mall/admin/cms/article/list',
order: 9,
groups: [
- { id: 'cms-manage', title: '内容管理', order: 1 }
+ { id: 'cms-manage', title: '', order: 1 }
]
},
{
@@ -187,7 +187,10 @@ export const topMenus: TopMenu[] = [
order: 12,
groups: [
{ id: 'setting-system', title: '系统设置', order: 1 },
- { id: 'setting-application', title: '应用设置', order: 2 }
+ { id: 'setting-message', title: '通知管理', order: 2 },
+ { id: 'setting-auth', title: '权限管理', order: 3 },
+ { id: 'setting-delivery', title: '物流设置', order: 4 },
+ { id: 'setting-interface', title: '接口设置', order: 5 }
]
},
{
@@ -228,7 +231,7 @@ export const routes: RouteRecord[] = [
{
id: 'user_statistic',
title: '用户统计',
- path: '/pages/mall/admin/user/Statistic',
+ path: '/pages/mall/admin/user/statistics/index',
componentKey: 'UserStatistic',
parentId: 'user',
groupId: 'user-manage',
@@ -238,7 +241,7 @@ export const routes: RouteRecord[] = [
{
id: 'user_list',
title: '用户管理',
- path: '/pages/mall/admin/user/list',
+ path: '/pages/mall/admin/user/management/index',
componentKey: 'UserList',
parentId: 'user',
groupId: 'user-manage',
@@ -248,7 +251,7 @@ export const routes: RouteRecord[] = [
{
id: 'user_group',
title: '用户分组',
- path: '/pages/mall/admin/user/group',
+ path: '/pages/mall/admin/user/grouping/index',
componentKey: 'UserGroup',
parentId: 'user',
groupId: 'user-manage',
@@ -258,7 +261,7 @@ export const routes: RouteRecord[] = [
{
id: 'user_label',
title: '用户标签',
- path: '/pages/mall/admin/user/label',
+ path: '/pages/mall/admin/user/label/index',
componentKey: 'UserLabel',
parentId: 'user',
groupId: 'user-manage',
@@ -268,7 +271,7 @@ export const routes: RouteRecord[] = [
{
id: 'user_level',
title: '用户等级',
- path: '/pages/mall/admin/user/level',
+ path: '/pages/mall/admin/user/level/index',
componentKey: 'UserLevel',
parentId: 'user',
groupId: 'user-manage',
@@ -301,7 +304,7 @@ export const routes: RouteRecord[] = [
{
id: 'product_productClassify',
title: '商品分类',
- path: '/pages/mall/admin/product/classify',
+ path: '/pages/mall/admin/product/classification/index',
componentKey: 'ProductClassify',
parentId: 'product',
groupId: 'product-manage',
@@ -311,7 +314,7 @@ export const routes: RouteRecord[] = [
{
id: 'product_productAttr',
title: '商品规格',
- path: '/pages/mall/admin/product/attr',
+ path: '/pages/mall/admin/product/specifications/index',
componentKey: 'ProductAttr',
parentId: 'product',
groupId: 'product-manage',
@@ -321,7 +324,7 @@ export const routes: RouteRecord[] = [
{
id: 'product_paramList',
title: '商品参数',
- path: '/pages/mall/admin/product/param',
+ path: '/pages/mall/admin/product/parameters/index',
componentKey: 'ProductParam',
parentId: 'product',
groupId: 'product-manage',
@@ -331,7 +334,7 @@ export const routes: RouteRecord[] = [
{
id: 'product_labelList',
title: '商品标签',
- path: '/pages/mall/admin/product/label',
+ path: '/pages/mall/admin/product/labels/index',
componentKey: 'ProductLabel',
parentId: 'product',
groupId: 'product-manage',
@@ -341,7 +344,7 @@ export const routes: RouteRecord[] = [
{
id: 'product_protectionList',
title: '商品保障',
- path: '/pages/mall/admin/product/protection',
+ path: '/pages/mall/admin/product/protection/index',
componentKey: 'ProductProtection',
parentId: 'product',
groupId: 'product-manage',
@@ -351,7 +354,7 @@ export const routes: RouteRecord[] = [
{
id: 'product_productEvaluate',
title: '商品评论',
- path: '/pages/mall/admin/product/reply',
+ path: '/pages/mall/admin/product/reviews/index',
componentKey: 'ProductReply',
parentId: 'product',
groupId: 'product-manage',
@@ -892,9 +895,10 @@ export const routes: RouteRecord[] = [
},
// ========== 设置模块 ==========
+ // 1. 系统设置
{
id: 'setting_systemConfig',
- title: '系统配置',
+ title: '系统设置',
path: '/pages/mall/admin/setting/system/config',
componentKey: 'SettingSystemConfig',
parentId: 'setting',
@@ -902,27 +906,168 @@ export const routes: RouteRecord[] = [
auth: ['admin-setting-system-config'],
order: 1
},
+
+ // 2. 通知管理
{
- id: 'setting_systemAdmin',
- title: '管理员管理',
- path: '/pages/mall/admin/setting/system/admin',
- componentKey: 'SettingSystemAdmin',
+ id: 'setting_message',
+ title: '消息管理',
+ path: '/pages/mall/admin/setting/message',
+ componentKey: 'SettingMessage',
parentId: 'setting',
- groupId: 'setting-system',
- auth: ['admin-setting-system-admin'],
+ groupId: 'setting-message',
+ order: 1
+ },
+ {
+ id: 'setting_agreement',
+ title: '协议管理',
+ path: '/pages/mall/admin/setting/agreement',
+ componentKey: 'SettingAgreement',
+ parentId: 'setting',
+ groupId: 'setting-message',
order: 2
},
{
- id: 'setting_systemRole',
- title: '角色管理',
- path: '/pages/mall/admin/setting/system/role',
- componentKey: 'SettingSystemRole',
+ id: 'setting_ticket',
+ title: '客服设置',
+ path: '/pages/mall/admin/setting/ticket',
+ componentKey: 'SettingTicket',
parentId: 'setting',
- groupId: 'setting-system',
- auth: ['admin-setting-system-role'],
+ groupId: 'setting-message',
order: 3
},
+ // 3. 权限管理
+ {
+ id: 'setting_auth_role',
+ title: '角色管理',
+ path: '/pages/mall/admin/setting/auth/role',
+ componentKey: 'SettingAuthRole',
+ parentId: 'setting',
+ groupId: 'setting-auth',
+ order: 1
+ },
+ {
+ id: 'setting_auth_admin',
+ title: '管理员管理',
+ path: '/pages/mall/admin/setting/auth/admin',
+ componentKey: 'SettingAuthAdmin',
+ parentId: 'setting',
+ groupId: 'setting-auth',
+ order: 2
+ },
+ {
+ id: 'setting_auth_permission',
+ title: '权限管理',
+ path: '/pages/mall/admin/setting/auth/permission',
+ componentKey: 'SettingAuthPermission',
+ parentId: 'setting',
+ groupId: 'setting-auth',
+ order: 3
+ },
+
+ // 4. 物流设置
+ {
+ id: 'setting_delivery_staff',
+ title: '配送员管理',
+ path: '/pages/mall/admin/setting/delivery/staff',
+ componentKey: 'SettingDeliveryStaff',
+ parentId: 'setting',
+ groupId: 'setting-delivery',
+ order: 1
+ },
+ {
+ id: 'setting_delivery_station',
+ title: '提货点管理',
+ path: '/pages/mall/admin/setting/delivery/station',
+ componentKey: 'SettingDeliveryStation',
+ parentId: 'setting',
+ groupId: 'setting-delivery',
+ order: 2
+ },
+ {
+ id: 'setting_delivery_template',
+ title: '运费模板',
+ path: '/pages/mall/admin/setting/delivery/template',
+ componentKey: 'SettingDeliveryTemplate',
+ parentId: 'setting',
+ groupId: 'setting-delivery',
+ order: 3
+ },
+
+ // 5. 接口设置
+ {
+ id: 'setting_interface_onepass_config',
+ title: '总平台配置',
+ path: '/pages/mall/admin/setting/interface/onepass/config',
+ componentKey: 'SettingInterfaceOnepassConfig',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 1
+ },
+ {
+ id: 'setting_interface_onepass_index',
+ title: '账号列表',
+ path: '/pages/mall/admin/setting/interface/onepass/index',
+ componentKey: 'SettingInterfaceOnepassIndex',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 2
+ },
+ {
+ id: 'setting_interface_storage',
+ title: '存储配置',
+ path: '/pages/mall/admin/setting/interface/storage',
+ componentKey: 'SettingInterfaceStorage',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 3
+ },
+ {
+ id: 'setting_interface_collect',
+ title: '商品采集',
+ path: '/pages/mall/admin/setting/interface/collect',
+ componentKey: 'SettingInterfaceCollect',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 4
+ },
+ {
+ id: 'setting_interface_logistics',
+ title: '物流查询',
+ path: '/pages/mall/admin/setting/interface/logistics',
+ componentKey: 'SettingInterfaceLogistics',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 5
+ },
+ {
+ id: 'setting_interface_esheet',
+ title: '电子面单',
+ path: '/pages/mall/admin/setting/interface/e-sheet',
+ componentKey: 'SettingInterfaceESheet',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 6
+ },
+ {
+ id: 'setting_interface_sms',
+ title: '短信接口',
+ path: '/pages/mall/admin/setting/interface/sms',
+ componentKey: 'SettingInterfaceSms',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 7
+ },
+ {
+ id: 'setting_interface_payment',
+ title: '商城支付',
+ path: '/pages/mall/admin/setting/interface/payment',
+ componentKey: 'SettingInterfacePayment',
+ parentId: 'setting',
+ groupId: 'setting-interface',
+ order: 8
+ },
+
// ========== 分销模块 ==========
{
id: 'distribution_statistic',
@@ -934,23 +1079,59 @@ export const routes: RouteRecord[] = [
order: 1
},
{
- id: 'distribution_list',
- title: '分销员列表',
- path: '/pages/mall/admin/distribution/list',
- componentKey: 'DistributionList',
+ id: 'distribution_promoter',
+ title: '分销员管理',
+ path: '/pages/mall/admin/distribution/promoter/index',
+ componentKey: 'DistributionPromoter',
parentId: 'distribution',
groupId: 'distribution-manage',
order: 2
},
{
- id: 'distribution_config',
- title: '分销设置',
- path: '/pages/mall/admin/distribution/config',
- componentKey: 'DistributionConfig',
+ id: 'distribution_level',
+ title: '分销等级',
+ path: '/pages/mall/admin/distribution/level/index',
+ componentKey: 'DistributionLevel',
parentId: 'distribution',
groupId: 'distribution-manage',
order: 3
},
+ {
+ id: 'distribution_setting',
+ title: '分销设置',
+ path: '/pages/mall/admin/distribution/setting/index',
+ componentKey: 'DistributionSetting',
+ parentId: 'distribution',
+ groupId: 'distribution-manage',
+ order: 4
+ },
+ {
+ id: 'division_list',
+ title: '事业部管理',
+ path: '/pages/mall/admin/distribution/division/list',
+ componentKey: 'DivisionList',
+ parentId: 'distribution',
+ groupId: 'distribution-manage',
+ order: 5
+ },
+ {
+ id: 'division_agent',
+ title: '代理商管理',
+ path: '/pages/mall/admin/distribution/division/agent',
+ componentKey: 'DivisionAgent',
+ parentId: 'distribution',
+ groupId: 'distribution-manage',
+ order: 6
+ },
+ {
+ id: 'division_apply',
+ title: '事业部申请',
+ path: '/pages/mall/admin/distribution/division/apply',
+ componentKey: 'DivisionApply',
+ parentId: 'distribution',
+ groupId: 'distribution-manage',
+ order: 7
+ },
// ========== 客服模块 ==========
{
@@ -1055,7 +1236,7 @@ export const routes: RouteRecord[] = [
order: 6
},
{
- id: 'decoration_link',
+ id: 'DecorationLink',
title: '链接管理',
path: '/pages/mall/admin/decoration/link',
componentKey: 'DecorationLink',
@@ -1064,6 +1245,33 @@ export const routes: RouteRecord[] = [
order: 7
},
+ // ========== 设置模块 (1:1 复刻 CRMEB 路由结构) ==========
+ // 通知管理
+ { id: 'setting_message_index', title: '消息管理', path: '/pages/mall/admin/setting/message', componentKey: 'SettingMessageIndex', parentId: 'setting', groupId: 'setting-message', order: 1 },
+ { id: 'setting_protocol_index', title: '协议设置', path: '/pages/mall/admin/setting/agreement', componentKey: 'SettingProtocolIndex', parentId: 'setting', groupId: 'setting-message', order: 2 },
+ { id: 'setting_ticket_index', title: '小票配置', path: '/pages/mall/admin/setting/ticket', componentKey: 'SettingTicketIndex', parentId: 'setting', groupId: 'setting-message', order: 3 },
+
+ // 权限管理
+ { id: 'setting_auth_admin', title: '管理员管理', path: '/pages/mall/admin/setting/auth/admin', componentKey: 'SettingAuthAdmin', parentId: 'setting', groupId: 'setting-auth', order: 1 },
+ { id: 'setting_auth_role', title: '角色管理', path: '/pages/mall/admin/setting/auth/role', componentKey: 'SettingAuthRole', parentId: 'setting', groupId: 'setting-auth', order: 2 },
+ { id: 'setting_auth_menu', title: '菜单管理', path: '/pages/mall/admin/setting/auth/permission', componentKey: 'SettingAuthMenu', parentId: 'setting', groupId: 'setting-auth', order: 3 },
+
+ // 物流设置
+ { id: 'setting_delivery_courier', title: '配送员管理', path: '/pages/mall/admin/setting/delivery/staff', componentKey: 'SettingDeliveryCourier', parentId: 'setting', groupId: 'setting-delivery', order: 1 },
+ { id: 'setting_delivery_pickup_list', title: '提货点', path: '/pages/mall/admin/setting/delivery/station', componentKey: 'SettingDeliveryPickupList', parentId: 'setting', groupId: 'setting-delivery', order: 2 },
+ { id: 'setting_delivery_verifier', title: '核销员', path: '/pages/mall/admin/setting/delivery/station', componentKey: 'SettingDeliveryVerifier', parentId: 'setting', groupId: 'setting-delivery', order: 3 },
+ { id: 'setting_delivery_freight', title: '运费模板', path: '/pages/mall/admin/setting/delivery/template', componentKey: 'SettingDeliveryFreight', parentId: 'setting', groupId: 'setting-delivery', order: 4 },
+
+ // 接口设置
+ { id: 'setting_api_yht_page', title: '一号通页面', path: '/pages/mall/admin/setting/interface/onepass/index', componentKey: 'SettingApiYhtPage', parentId: 'setting', groupId: 'setting-interface', order: 1 },
+ { id: 'setting_api_yht_config', title: '一号通配置', path: '/pages/mall/admin/setting/interface/onepass/config', componentKey: 'SettingApiYhtConfig', parentId: 'setting', groupId: 'setting-interface', order: 2 },
+ { id: 'setting_api_storage', title: '系统存储配置', path: '/pages/mall/admin/setting/interface/storage', componentKey: 'SettingApiStorage', parentId: 'setting', groupId: 'setting-interface', order: 3 },
+ { id: 'setting_api_collect', title: '商品采集配置', path: '/pages/mall/admin/setting/interface/collect', componentKey: 'SettingApiCollect', parentId: 'setting', groupId: 'setting-interface', order: 4 },
+ { id: 'setting_api_logistics', title: '物流查询配置', path: '/pages/mall/admin/setting/interface/logistics', componentKey: 'SettingApiLogistics', parentId: 'setting', groupId: 'setting-interface', order: 5 },
+ { id: 'setting_api_waybill', title: '电子面单配置', path: '/pages/mall/admin/setting/interface/e-sheet', componentKey: 'SettingApiWaybill', parentId: 'setting', groupId: 'setting-interface', order: 6 },
+ { id: 'setting_api_sms', title: '短信接口配置', path: '/pages/mall/admin/setting/interface/sms', componentKey: 'SettingApiSms', parentId: 'setting', groupId: 'setting-interface', order: 7 },
+ { id: 'setting_api_pay', title: '商城支付配置', path: '/pages/mall/admin/setting/interface/payment', componentKey: 'SettingApiPay', parentId: 'setting', groupId: 'setting-interface', order: 8 },
+
// ========== 应用模块 ==========
{
id: 'app_statistic',
diff --git a/layouts/admin/router/settingSubSiderMenu.uts b/layouts/admin/router/settingSubSiderMenu.uts
new file mode 100644
index 00000000..b26a8313
--- /dev/null
+++ b/layouts/admin/router/settingSubSiderMenu.uts
@@ -0,0 +1,42 @@
+export type MenuNode = {
+ id: string
+ title: string
+ type: 'group' | 'page'
+ path?: string // type=page 必填
+ children?: MenuNode[] // type=group 必填
+}
+
+export const settingSubSiderMenu: MenuNode[] = [
+ { id: 'setting_message_index', title: '消息管理', type: 'page', path: '/pages/mall/admin/setting/message' },
+ { id: 'setting_protocol_index', title: '协议设置', type: 'page', path: '/pages/mall/admin/setting/agreement' },
+ { id: 'setting_ticket_index', title: '小票配置', type: 'page', path: '/pages/mall/admin/setting/ticket' },
+ { id: 'auth_group', title: '管理权限', type: 'group', children: [
+ { id: 'setting_auth_admin', title: '管理员管理', type: 'page', path: '/pages/mall/admin/setting/auth/admin' },
+ { id: 'setting_auth_role', title: '角色管理', type: 'page', path: '/pages/mall/admin/setting/auth/role' },
+ { id: 'setting_auth_menu', title: '菜单管理', type: 'page', path: '/pages/mall/admin/setting/auth/permission' }
+ ]
+ },
+ { id: 'delivery_group', title: '发货设置', type: 'group', children: [
+ { id: 'setting_delivery_courier', title: '配送员管理', type: 'page', path: '/pages/mall/admin/setting/delivery/staff' },
+ { id: 'pickup_order_group', title: '提货点设置', type: 'group', children: [
+ { id: 'setting_delivery_pickup_list', title: '提货点', type: 'page', path: '/pages/mall/admin/setting/delivery/station' },
+ { id: 'setting_delivery_verifier', title: '核销员', type: 'page', path: '/pages/mall/admin/setting/delivery/station' },
+ { id: 'setting_delivery_freight', title: '运费模板', type: 'page', path: '/pages/mall/admin/setting/delivery/template' }
+ ]}
+ ]
+ },
+ { id: 'api_group', title: '接口配置', type: 'group', children: [
+ { id: 'yh_tong_group', title: '一号通', type: 'group', children: [
+ { id: 'setting_api_yht_page', title: '一号通页面', type: 'page', path: '/pages/mall/admin/setting/interface/onepass/index' },
+ { id: 'setting_api_yht_config', title: '一号通配置', type: 'page', path: '/pages/mall/admin/setting/interface/onepass/config' }
+ ]
+ },
+ { id: 'setting_api_storage', title: '系统存储配置', type: 'page', path: '/pages/mall/admin/setting/interface/storage' },
+ { id: 'setting_api_collect', title: '商品采集配置', type: 'page', path: '/pages/mall/admin/setting/interface/collect' },
+ { id: 'setting_api_logistics', title: '物流查询配置', type: 'page', path: '/pages/mall/admin/setting/interface/logistics' },
+ { id: 'setting_api_waybill', title: '电子面单配置', type: 'page', path: '/pages/mall/admin/setting/interface/e-sheet' },
+ { id: 'setting_api_sms', title: '短信接口配置', type: 'page', path: '/pages/mall/admin/setting/interface/sms' },
+ { id: 'setting_api_pay', title: '商城支付配置', type: 'page', path: '/pages/mall/admin/setting/interface/payment' }
+ ]
+ }
+]
diff --git a/layouts/admin/store/adminNavStore.uts b/layouts/admin/store/adminNavStore.uts
index 62305e0c..de3ab582 100644
--- a/layouts/admin/store/adminNavStore.uts
+++ b/layouts/admin/store/adminNavStore.uts
@@ -11,6 +11,7 @@ import {
buildDefaultTabs,
getTopMenus
} from '@/layouts/admin/router/adminRoutes.uts'
+import { addView, activeFullPath, visitedViews } from './tagsViewStore.uts'
/**
* 标签页类型
@@ -32,19 +33,40 @@ export const activeTopMenuId = ref('home')
/** 当前激活的路由ID */
export const activeRouteId = ref('home_index')
+/** 记录每个一级模块上一次访问的二级路由ID (CRMEB 体验增强) */
+export const lastSubIdByMenu = ref>({})
+
+/** 标记是否由用户手动关闭了 SubSider (移动端) */
+export const isManualClosed = ref(false)
+
/** 打开的标签页列表 */
export const tabs = ref([])
-/** 是否折叠主侧边栏 */
+/** 是否折叠主侧边栏 (CRMEB: 70px) */
export const isMainAsideCollapsed = ref(false)
-/** 是否显示二级侧边栏 */
-export const showSubSider = computed(() => {
- const topMenus = getTopMenus()
- const activeMenu = topMenus.find(m => m.id === activeTopMenuId.value)
- return activeMenu ? activeMenu.groups.length > 0 : false
+/** 是否显示二级侧边栏状态控制 */
+export const showSubSider = ref(true)
+
+/** 屏幕宽度 */
+export const windowWidth = ref(1024)
+
+/** 布局模式:desktop | tablet | mobile */
+export const layoutMode = computed(() => {
+ if (windowWidth.value < 768) return 'mobile'
+ if (windowWidth.value < 1200) return 'tablet'
+ return 'desktop'
})
+/** 是否为移动端简易判断 */
+export const isMobile = computed(() => layoutMode.value === 'mobile')
+
+/** 移动端开关 */
+export const isMobileMenuOpen = ref(false)
+
+/** 遮罩层开关 (用于 tablet 的 subSider overlay 和 mobile 的 aside overlay) */
+export const isOverlayVisible = ref(false)
+
// ============================================
// Actions
// ============================================
@@ -67,6 +89,8 @@ export function openRoute(routeId: string, addTab: boolean = true): void {
// 更新一级菜单选中态
if (route.parentId) {
activeTopMenuId.value = route.parentId
+ // 记录该模块最后访问的子路由
+ lastSubIdByMenu.value[route.parentId] = routeId
} else {
// 首页等顶级路由
activeTopMenuId.value = routeId.split('_')[0]
@@ -101,6 +125,10 @@ function addTabItem(route: RouteRecord): void {
isAffix: route.isAffix || false
})
}
+
+ // 更新新版 TagsViewStore
+ addView(route, route.path)
+ activeFullPath.value = route.path
}
/**
@@ -165,6 +193,13 @@ export function toggleMainAsideCollapse(): void {
isMainAsideCollapsed.value = !isMainAsideCollapsed.value
}
+/**
+ * 切换二级侧边栏显示状态 (Desktop 模式)
+ */
+export function toggleSubSider(): void {
+ showSubSider.value = !showSubSider.value
+}
+
/**
* 初始化导航状态
* 在 AdminLayout 组件 onMounted 时调用
@@ -179,6 +214,11 @@ export function initNavState(): void {
isAffix: r.isAffix || false
}))
+ // 初始化 TagsViewStore
+ defaultTabs.forEach(r => {
+ addView(r, r.path)
+ })
+
// 打开首页
openRoute('home_index', false)
}
diff --git a/layouts/admin/store/tagsViewStore.uts b/layouts/admin/store/tagsViewStore.uts
new file mode 100644
index 00000000..01497a4f
--- /dev/null
+++ b/layouts/admin/store/tagsViewStore.uts
@@ -0,0 +1,126 @@
+/**
+ * TagsView 状态管理
+ * 复刻 CRMEB 风格的标签栏逻辑
+ */
+
+import { ref } from 'vue'
+import type { RouteRecord } from '@/layouts/admin/router/adminRoutes.uts'
+
+/**
+ * 标签页视图类型
+ */
+export type TagView = {
+ id: string // 对应路由ID
+ title: string // 标题
+ path: string // 基础路径
+ fullPath: string // 完整路径(包含参数)
+ name: string // 组件Key
+ meta: {
+ affix?: boolean
+ noCache?: boolean
+ }
+}
+
+/** 访问过的页面列表 */
+export const visitedViews = ref([])
+
+/** 缓存的页面列表 (用于 keep-alive) */
+export const cachedViews = ref([])
+
+/** 开启的标签页详情 */
+export const activeFullPath = ref('')
+
+// ============================================
+// Actions
+// ============================================
+
+/**
+ * 添加视图
+ */
+export function addView(route: RouteRecord, fullPath: string): void {
+ // 1. 添加到访问列表
+ if (visitedViews.value.some(v => v.fullPath === fullPath)) return
+
+ // 如果 ID 相同但 fullPath 不同(参数变化), 则更新或者替换
+ const existingIndex = visitedViews.value.findIndex(v => v.id === route.id)
+
+ const newView: TagView = {
+ id: route.id,
+ title: route.title,
+ path: route.path,
+ fullPath: fullPath,
+ name: route.componentKey,
+ meta: {
+ affix: route.isAffix || false,
+ noCache: false // 默认为缓存,如果有特殊需求可扩展
+ }
+ }
+
+ if (existingIndex > -1) {
+ // 同一路由不同参数, 更新记录
+ visitedViews.value[existingIndex] = newView
+ } else {
+ visitedViews.value.push(newView)
+ }
+
+ // 2. 添加到缓存列表
+ if (!route.componentKey) return
+ if (cachedViews.value.includes(route.componentKey)) return
+ cachedViews.value.push(route.componentKey)
+}
+
+/**
+ * 删除视图
+ */
+export function delView(view: TagView): void {
+ const index = visitedViews.value.findIndex(v => v.fullPath === view.fullPath)
+ if (index > -1 && !visitedViews.value[index].meta.affix) {
+ visitedViews.value.splice(index, 1)
+ }
+
+ const cacheIndex = cachedViews.value.indexOf(view.name)
+ if (cacheIndex > -1) {
+ cachedViews.value.splice(cacheIndex, 1)
+ }
+}
+
+/**
+ * 关闭其他标签
+ */
+export function delOthersViews(view: TagView): void {
+ visitedViews.value = visitedViews.value.filter(v => v.meta.affix || v.fullPath === view.fullPath)
+ cachedViews.value = visitedViews.value.map(v => v.name)
+}
+
+/**
+ * 关闭右侧标签
+ */
+export function delRightTags(view: TagView): void {
+ const index = visitedViews.value.findIndex(v => v.fullPath === view.fullPath)
+ if (index === -1) return
+
+ visitedViews.value = visitedViews.value.filter((v, i) => {
+ return i <= index || v.meta.affix
+ })
+ cachedViews.value = visitedViews.value.map(v => v.name)
+}
+
+/**
+ * 关闭所有
+ */
+export function delAllViews(): void {
+ const affixTags = visitedViews.value.filter(v => v.meta.affix)
+ visitedViews.value = affixTags
+ cachedViews.value = affixTags.map(v => v.name)
+}
+
+/**
+ * 刷新当前视图 (通常结合全局事件通知组件)
+ */
+export function refreshView(view: TagView): void {
+ const index = cachedViews.value.indexOf(view.name)
+ if (index > -1) {
+ cachedViews.value.splice(index, 1)
+ }
+ // 通知框架重新加载该组件的逻辑通常在组件内部处理或通过 key 变化
+}
diff --git a/layouts/admin/styles/admin-responsive.css b/layouts/admin/styles/admin-responsive.css
new file mode 100644
index 00000000..52c6dda8
--- /dev/null
+++ b/layouts/admin/styles/admin-responsive.css
@@ -0,0 +1,96 @@
+/* 统一 KPI 统计网格响应式规范 */
+
+.kpi-grid {
+ display: grid !important;
+ gap: 12px;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+/* 规则 1:屏幕宽度 >= 1200px -> 固定 4 列 */
+@media (min-width: 1200px) {
+ .kpi-grid {
+ grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
+ }
+}
+
+/* 规则 2:768px <= 屏幕宽度 < 1200px -> 固定 2 列 */
+@media (min-width: 768px) and (max-width: 1199.98px) {
+ .kpi-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
+ }
+}
+
+/* 规则 3:屏幕宽度 < 768px -> 固定 1 列 */
+@media (max-width: 767.98px) {
+ .kpi-grid {
+ grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
+ }
+}
+
+/* 强制子项允许收缩,防止内部长文本撑爆网格 */
+.kpi-grid > *,
+.kpi-grid-6 > * {
+ min-width: 0 !important;
+ flex: none !important; /* 覆盖旧的 flex 逻辑 */
+ width: auto !important; /* 让 grid 控制宽度 */
+}
+
+/* 6-2-1 网格规范 (对标 CRMEB 统计概况) */
+.kpi-grid-6 {
+ display: grid !important;
+ gap: 12px;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+@media (min-width: 1200px) {
+ .kpi-grid-6 {
+ grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 1199.98px) {
+ .kpi-grid-6 {
+ grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .kpi-grid-6 {
+ grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
+ }
+}
+
+/* ===== 后台通用紧凑布局规范 (CRMEB 1:1) ===== */
+
+/* 页面根容器: 去除各页面自带的 padding,由 Layout 统一管理 */
+.admin-page {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ padding: 0 !important;
+ margin: 0 !important;
+}
+
+/* 垂直区块容器: 统一控制卡片、组件之间的间距 */
+.admin-sections {
+ display: flex;
+ flex-direction: column;
+ gap: var(--admin-section-gap);
+ width: 100%;
+}
+
+/* 通用网格: 用于图表布局等 */
+.admin-grid {
+ display: grid;
+ gap: var(--admin-section-gap);
+ width: 100%;
+}
+
+/* 统一卡片内部间距: 替代业务组件或页面内硬编码的 padding */
+.admin-card {
+ padding: var(--admin-card-padding) !important;
+ background: #ffffff;
+ border-radius: 4px;
+}
diff --git a/main.uts b/main.uts
index da42848e..3e40f0b5 100644
--- a/main.uts
+++ b/main.uts
@@ -7,11 +7,9 @@ export function createApp() {
// 注册 i18n 全局属性,使组件可以使用 $t 方法
app.config.globalProperties.$t = (key: string, values?: any, locale?: string): string => {
- if (!i18n.global) {
- console.error('i18n is not initialized')
- return key
- }
- return i18n.global.t(key, values, locale) || key
+ // 临时方案:移除对未定义 i18n 的引用,直接返回 Key
+ // 如果之后需要 i18n,应正确导入并初始化
+ return key
}
return { app }
diff --git a/package-lock.json b/package-lock.json
index ed7f4ffe..6f522917 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,9 @@
"echarts": "^6.0.0"
},
"devDependencies": {
- "@dcloudio/types": "^3.4.29"
+ "@dcloudio/types": "^3.4.29",
+ "eslint": "^8.57.0",
+ "eslint-plugin-vue": "^9.21.1"
}
},
"node_modules/@dcloudio/types": {
@@ -18,6 +20,370 @@
"integrity": "sha512-7uBInqqYLoLmQMqlzW4FsYCEHTUgTkrtZVsFGgQnJT7ZCA12U9y0ovrqAM1ZWkLruHYfOS7xIqO77Who6UBLJg==",
"dev": true
},
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.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/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/echarts": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-6.0.0.tgz",
@@ -28,11 +394,1006 @@
"zrender": "6.0.0"
}
},
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-vue": {
+ "version": "9.33.0",
+ "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz",
+ "integrity": "sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "globals": "^13.24.0",
+ "natural-compare": "^1.4.0",
+ "nth-check": "^2.1.1",
+ "postcss-selector-parser": "^6.0.15",
+ "semver": "^7.6.3",
+ "vue-eslint-parser": "^9.4.3",
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "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",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "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",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.23",
+ "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz",
+ "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "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/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "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"
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "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",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vue-eslint-parser": {
+ "version": "9.4.3",
+ "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
+ "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "eslint-scope": "^7.1.1",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.3.1",
+ "esquery": "^1.4.0",
+ "lodash": "^4.17.21",
+ "semver": "^7.3.6"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/xml-name-validator": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/zrender": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz",
diff --git a/pages.json b/pages.json
index b318b18b..929542cd 100644
--- a/pages.json
+++ b/pages.json
@@ -453,19 +453,54 @@
"root": "pages/mall/admin",
"pages": [
{
- "path": "user-management",
+ "path": "user/management/index",
"style": {
"navigationBarTitleText": "用户管理",
"navigationStyle": "custom"
}
},
{
- "path": "product-management",
+ "path": "product/product-management/index",
"style": {
"navigationBarTitleText": "商品管理",
"navigationStyle": "custom"
}
},
+ {
+ "path": "order/list",
+ "style": {
+ "navigationBarTitleText": "订单列表",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "order/order-statistics/index",
+ "style": {
+ "navigationBarTitleText": "订单统计",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "order/order-configuration/index",
+ "style": {
+ "navigationBarTitleText": "订单配置",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "order/aftersales-order/index",
+ "style": {
+ "navigationBarTitleText": "售后订单",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "order/write-off-records/index",
+ "style": {
+ "navigationBarTitleText": "核销记录",
+ "navigationStyle": "custom"
+ }
+ },
{
"path": "order-management",
"style": {
@@ -481,19 +516,12 @@
}
},
{
- "path": "user-statistics",
+ "path": "user/statistics/index",
"style": {
"navigationBarTitleText": "用户统计",
"navigationStyle": "custom"
}
},
- {
- "path": "system-settings",
- "style": {
- "navigationBarTitleText": "系统设置",
- "navigationStyle": "custom"
- }
- },
{
"path": "subscription/plan-management",
"style": {
@@ -506,6 +534,48 @@
"navigationBarTitleText": "用户订阅管理"
}
},
+ {
+ "path": "distribution/setting/index",
+ "style": {
+ "navigationBarTitleText": "分销设置",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "distribution/promoter/index",
+ "style": {
+ "navigationBarTitleText": "分销员管理",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "distribution/level/index",
+ "style": {
+ "navigationBarTitleText": "分销等级管理",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "distribution/division/list",
+ "style": {
+ "navigationBarTitleText": "事业部管理",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "distribution/division/agent",
+ "style": {
+ "navigationBarTitleText": "代理商列表",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "distribution/division/apply",
+ "style": {
+ "navigationBarTitleText": "事业部申请",
+ "navigationStyle": "custom"
+ }
+ },
{
"path": "marketing/coupon/list",
"style": {
@@ -633,4 +703,4 @@
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#F8F8F8"
}
-}
\ No newline at end of file
+}
diff --git a/pages/mall/admin/distribution/division/agent.uvue b/pages/mall/admin/distribution/division/agent.uvue
new file mode 100644
index 00000000..31286f87
--- /dev/null
+++ b/pages/mall/admin/distribution/division/agent.uvue
@@ -0,0 +1,83 @@
+
+
+
+
+
+ 代理商查询:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.uid }}
+
+
+
+ {{ item.name }}
+ {{ item.ratio }}%
+ {{ item.staffCount }}
+ {{ item.endTime }}
+
+
+
+
+ 编辑
+ |
+ 查看
+ |
+ 员工
+ |
+ 删除
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mall/admin/distribution/division/apply.uvue b/pages/mall/admin/distribution/division/apply.uvue
new file mode 100644
index 00000000..e5a50e0b
--- /dev/null
+++ b/pages/mall/admin/distribution/division/apply.uvue
@@ -0,0 +1,89 @@
+
+
+
+
+
+ 搜索:
+
+
+
+
+
+
+
+
+
+
+ {{ tab }}
+
+
+
+
+
+
+ {{ item.uid }}
+ {{ item.name }}
+ {{ item.phone }}
+ {{ item.deptName }}
+
+
+
+ {{ item.time }}
+
+ {{ item.statusText }}
+
+ {{ item.code }}
+
+ 同意
+ |
+ 拒绝
+ |
+ 删除
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mall/admin/distribution/division/list.uvue b/pages/mall/admin/distribution/division/list.uvue
new file mode 100644
index 00000000..de109dc5
--- /dev/null
+++ b/pages/mall/admin/distribution/division/list.uvue
@@ -0,0 +1,83 @@
+
+
+
+
+
+ 搜索:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.uid }}
+
+
+
+ {{ item.name }}
+ {{ item.code }}
+ {{ item.ratio }}%
+ {{ item.agentCount }}
+ {{ item.endTime }}
+
+
+
+
+ 查看代理商
+ |
+ 编辑
+ |
+ 删除
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mall/admin/distribution/level/index.uvue b/pages/mall/admin/distribution/level/index.uvue
new file mode 100644
index 00000000..3f1bf95a
--- /dev/null
+++ b/pages/mall/admin/distribution/level/index.uvue
@@ -0,0 +1,95 @@
+
+
+
+
+
+ 是否显示:
+ 全部▼
+
+
+ 等级名称:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.id }}
+
+
+
+ {{ item.name }}
+ {{ item.level }}
+ {{ item.percent1 }}%
+ {{ item.percent2 }}%
+ {{ item.taskTotal }}
+ {{ item.taskFinish }}
+
+
+
+
+ 等级任务
+ |
+ 编辑
+ |
+ 删除
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mall/admin/distribution/promoter/index.uvue b/pages/mall/admin/distribution/promoter/index.uvue
new file mode 100644
index 00000000..60364207
--- /dev/null
+++ b/pages/mall/admin/distribution/promoter/index.uvue
@@ -0,0 +1,114 @@
+
+
+
+
+
+ 时间选择:
+
+ 开始日期 - 结束日期
+ 📅
+
+
+
+ 搜索:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.id }}
+
+
+
+
+
+ 昵称:{{ item.nickname }}
+ 姓名:{{ item.name }}
+ 电话:{{ item.phone }}
+
+
+ {{ item.level }}
+ {{ item.userCount }}
+ {{ item.orderCount }}
+ {{ item.orderAmount }}
+ {{ item.commissionTotal }}
+ {{ item.withdrawnAmount }}
+ {{ item.withdrawCount }}
+ {{ item.unwithdrawnAmount }}
+
+ 推广人
+ |
+ 更多
+ ▼
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mall/admin/distribution/setting/index.uvue b/pages/mall/admin/distribution/setting/index.uvue
new file mode 100644
index 00000000..89a1d864
--- /dev/null
+++ b/pages/mall/admin/distribution/setting/index.uvue
@@ -0,0 +1,508 @@
+
+
+
+
+
+ {{ tab }}
+
+
+
+
+
+
+
+ 分销启用:
+ form.statue = e.detail.value">
+
+
+
+ 商城分销功能开启关闭
+
+
+
+ 分销模式:
+ form.extract_type = e.detail.value">
+
+
+
+
+ 人人分销"默认每个人都可以分销,“指定分销”仅后台手动设置推广员,“满额分销”指用户购买商品满足消费金额后自动开启分销
+
+
+
+ 分销关系绑定:
+ form.bind_type = e.detail.value">
+
+
+
+ 所有用户”指所有没有上级推广人的用户点击或扫码即绑定分销关系,“新用户”指新注册的用户或首次进入系统的用户才会绑定推广关系
+
+
+
+ 绑定模式:
+ form.store_brokerage_binding_status = e.detail.value">
+
+
+
+
+ 永久”一次绑定永久有效,“有效期”绑定后一段时间内有效,“临时”临时有效
+
+
+
+ 分销海报图:
+
+
+
+ +
+
+
+ 个人中心分销海报图片,建议尺寸600x1000
+
+
+
+ 分销层级:
+ form.brokerage_level = e.detail.value">
+
+
+
+ 分销层级,一级是只返上一层的佣金,二级是返上级 and 上上级的佣金
+
+
+
+ 事业部开关:
+ form.is_area_manager = e.detail.value">
+
+
+
+ 事业部开关,关闭后不计算事业部佣金
+
+
+
+ 代理商申请开关:
+ form.is_agent_apply = e.detail.value">
+
+
+
+ 控制移动端我的推广页面的代理商申请按钮是否显示
+
+
+
+ 佣金悬浮窗开关:
+ form.is_commission_window = e.detail.value">
+
+
+
+ 佣金悬浮窗开关,关闭之后,商品详情不显示佣金悬浮窗
+
+
+
+
+
+
+
+
+ 自购返佣:
+ form.is_self_brokerage = e.detail.value">
+
+
+
+ 是否开启自购返佣(开启:分销员自己购买商品,享受一级返佣,上级享受二级返佣;关闭:分销员自己购买商品没有返佣)
+
+
+
+ 购买付费会员返佣:
+ form.is_member_brokerage = e.detail.value">
+
+
+
+ 购买付费会员是否按照设置的佣金比例进行返佣
+
+
+
+ 返佣类型:
+ form.brokerage_type = e.detail.value">
+
+
+
+ 选择返佣类型,按照商品价格返佣(按照商品售价计算返佣金额)以及按照实际支付价格返佣(按照商品的实际支付价格计算返佣)
+
+
+
+ 推广用户返佣:
+ form.is_promoter_brokerage = e.detail.value">
+
+
+
+ 分销推广用户获取佣金
+
+
+
+ 推广佣金单价:
+
+ form.promoter_brokerage_price = e.detail.value" />
+
+ 分销推广佣金单价(每推广一个用户)
+
+
+
+ 每日推广佣金上限:
+
+ form.promoter_brokerage_day_max = e.detail.value" />
+
+ 每日推广佣金上限(0:不发佣金;-1:不限制;最好是推广佣金单价的整数倍)
+
+
+
+ 一级返佣比例:
+
+ form.store_brokerage_ratio = e.detail.value" />
+
+ 订单交易成功后给上级返佣的比例0 - 100,例:5 = 反订单商品金额的5%
+
+
+
+ 二级返佣比例:
+
+ form.store_brokerage_two_ratio = e.detail.value" />
+
+ 订单交易成功后给上上级返佣的比例0 - 100,例:5 = 反订单商品金额 of 5%
+
+
+
+ 冻结时间:
+
+ form.extract_frozen_time = e.detail.value" />
+
+ 防止用户退款,佣金被提现了,所以需要设置佣金冻结时间(天)
+
+
+
+
+
+
+
+
+ 提现最低金额:
+ form.user_extract_min_price = e.detail.value" />
+ 用户提现最低金额限制
+
+
+
+ 提现银行卡:
+
+ 配置提现银行卡类型,每个银行换行
+
+
+
+ 提现方式:
+ form.extract_type_list = e.detail.value">
+
+
+
+
+ 开启后用户可以选择该提现方式
+
+
+
+ 微信提现:
+ form.wechat_extract_type = e.detail.value">
+
+
+
+ 微信提现方式:手动线下转账,自动转账到零钱(需开通商家转账到零钱)
+
+
+
+ 支付宝提现:
+ form.alipay_extract_type = e.detail.value">
+
+
+
+ 支付宝提现方式:手动线下转账,自动转账到余额(需开通支付宝转账)
+
+
+
+ 提现手续费:
+ form.user_extract_fee = e.detail.value" />
+ 提现手续费百分比,范围0-100,0为无提现手续费,例:设置10,即收取10%手续费,提现100元,到账90元,10元手续费
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/docs/RESPONSIVE_LAYOUT_GUIDE.md b/pages/mall/admin/docs/RESPONSIVE_LAYOUT_GUIDE.md
new file mode 100644
index 00000000..b7618cce
--- /dev/null
+++ b/pages/mall/admin/docs/RESPONSIVE_LAYOUT_GUIDE.md
@@ -0,0 +1,85 @@
+# 管理后台响应式布局实现指南
+
+本文档总结了商城管理后台从固定布局到响应式布局的改造过程及核心技术点。
+
+## 1. 核心目标
+
+- **多终端适配**:确保后台在桌面端(宽屏)、平板端(中等屏幕)和移动端(窄屏)均能良好展示。
+- **自动适配状态管理**:系统能自动感知屏幕宽度并调整侧边栏显隐逻辑。
+- **布局平滑过渡**:侧边栏的收起、拉出及内容区的重排应具有良好的动画效果。
+
+## 2. 状态管理 (Store) 扩展
+
+在 [adminNavStore.uts](layouts/admin/store/adminNavStore.uts) 中引入了响应式状态:
+
+- `windowWidth`: 实时存储当前窗口宽度。
+- `isMobile`: 计算属性,当宽度小于 768px 时判定为移动端。
+- `isMobileMenuOpen`: 控制移动端模式下侧边栏的展开状态。
+
+```typescript
+export const windowWidth = ref(1024);
+export const isMobile = computed(() => windowWidth.value < 768);
+export const isMobileMenuOpen = ref(false);
+```
+
+## 3. 布局架构调整 (AdminLayout)
+
+[AdminLayout.uvue](layouts/admin/AdminLayout.uvue) 负责整体结构的响应式策略:
+
+### 3.1 监听并初始化
+
+在 `onMounted` 中初始化宽度并监听 `uni.onWindowResize`:
+
+```typescript
+onMounted(() => {
+ windowWidth.value = uni.getWindowInfo().windowWidth;
+ uni.onWindowResize((res) => {
+ windowWidth.value = res.size.windowWidth;
+ });
+});
+```
+
+### 3.2 侧边栏处理
+
+- **桌面端**:侧边栏常规展示,通过 `marginLeft` 为内容区腾出空间。
+- **移动端**:侧边栏通过 `position: absolute` 隐藏在屏幕外,通过 `translateX` 动画滑入。同时禁用二级侧边栏的常驻显示。
+
+### 3.3 移动端遮罩与切换
+
+- 引入 `mobile-mask` 遮罩层,点击遮罩自动关闭菜单。
+- [AdminHeader](layouts/admin/components/AdminHeader.uvue) 在移动端会显示 “☰” 切换按钮。
+
+## 4. 页面内容重排 (HomeIndex)
+
+[HomeIndex.uvue](layouts/admin/pages/HomeIndex.uvue) 利用 CSS 媒体查询实现内容区域的自适应:
+
+### 4.1 KPI 卡片流式布局
+
+使用 `flex-wrap: wrap` 配合 `min-width`:
+
+- **布局策略**:设置 `min-width: 250px` 作为安全边界,确保在 1200px 分辨率下依然能并排展示 4 个卡片。
+- **动态列数**:
+ - **宽屏 (>1200px)**: 4个卡片并排。
+ - **中屏 (768px - 1200px)**: 强制 2 个并排。
+ - **窄屏 (<768px)**: 1个卡片占满整行。
+- **高度控制**:统一固定为 `200px`。
+
+### 4.2 图表响应式
+
+- **垂直排列**:底部两个并排的图表在小屏下自动切换为垂直排列(`flex-direction: column`)。
+- **组件自适应**:图表组件内部利用父容器宽度自动伸缩。
+- **头部压缩**:移动端下,图表的配置项(如日期切换标签)由横向改为纵向,避免溢出。
+
+## 5. 组件化实践 (KpiMiniCard)
+
+统一使用了 [KpiMiniCard](pages/mall/admin/homePage/components/KpiMiniCard.uvue) 组件,确保:
+
+- 样式一致性。
+- 代码复用性。
+- 内部样式的可维护性。
+
+## 6. 使用建议
+
+- 后续开发新页面时,请优先使用 `stats-row` 和 `stat-card` 进行布局。
+- 对于复杂的表格页面,建议在移动端隐藏非核心列,或使用横向滚动条展示。
+- 所有的宽度判定建议遵循 768px 这一标准断点。
diff --git a/pages/mall/admin/homePage/components/KpiMiniCard.uvue b/pages/mall/admin/homePage/components/KpiMiniCard.uvue
index 89b9aee9..b7456b8e 100644
--- a/pages/mall/admin/homePage/components/KpiMiniCard.uvue
+++ b/pages/mall/admin/homePage/components/KpiMiniCard.uvue
@@ -81,7 +81,7 @@ const props = withDefaults(defineProps<{
const trendArrow = computed((): string => {
if (props.trend === 'up') return '▲'
if (props.trend === 'down') return '▼'
- return '•'
+ return ''
})
const trendClass = computed((): string => {
@@ -94,33 +94,43 @@ const trendClass = computed((): string => {
diff --git a/pages/mall/admin/homePage/index.uvue b/pages/mall/admin/homePage/index.uvue
index f9349d7f..05a54e81 100644
--- a/pages/mall/admin/homePage/index.uvue
+++ b/pages/mall/admin/homePage/index.uvue
@@ -1,24 +1,43 @@
-
-
+
+
+
+ 管理后台首页
+
+
+
-
+
diff --git a/pages/mall/admin/marketing-management.uvue b/pages/mall/admin/marketing-management.uvue
index 9921de20..57e1ddcd 100644
--- a/pages/mall/admin/marketing-management.uvue
+++ b/pages/mall/admin/marketing-management.uvue
@@ -1,14 +1,16 @@
-
-
+
+
+
-
- 页面参数(query)
- {{ params }}
+
+ 页面参数(query)
+ {{ params }}
+
@@ -27,13 +29,7 @@ onLoad((options) => {
diff --git a/pages/mall/admin/order-management.uvue b/pages/mall/admin/order-management.uvue
index 776621fe..71eba904 100644
--- a/pages/mall/admin/order-management.uvue
+++ b/pages/mall/admin/order-management.uvue
@@ -1,14 +1,16 @@
-
-
+
+
+
-
- 页面参数(query)
- {{ params }}
+
+ 页面参数(query)
+ {{ params }}
+
@@ -33,13 +35,7 @@ onLoad((options: Record) => {
diff --git a/pages/mall/admin/product-labels.uvue b/pages/mall/admin/product-labels.uvue
deleted file mode 100644
index 0fa9f92e..00000000
--- a/pages/mall/admin/product-labels.uvue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product-management.uvue b/pages/mall/admin/product-management.uvue
deleted file mode 100644
index ab91ffdb..00000000
--- a/pages/mall/admin/product-management.uvue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product-parameters.uvue b/pages/mall/admin/product-parameters.uvue
deleted file mode 100644
index 0c28fe61..00000000
--- a/pages/mall/admin/product-parameters.uvue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product-protection.uvue b/pages/mall/admin/product-protection.uvue
deleted file mode 100644
index f045f2ba..00000000
--- a/pages/mall/admin/product-protection.uvue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product-reviews.uvue b/pages/mall/admin/product-reviews.uvue
deleted file mode 100644
index aa0afb5b..00000000
--- a/pages/mall/admin/product-reviews.uvue
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product-specifications.uvue b/pages/mall/admin/product-specifications.uvue
deleted file mode 100644
index 9fde03b0..00000000
--- a/pages/mall/admin/product-specifications.uvue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product/classify.uvue b/pages/mall/admin/product/classification/index.uvue
similarity index 100%
rename from pages/mall/admin/product/classify.uvue
rename to pages/mall/admin/product/classification/index.uvue
diff --git a/pages/mall/admin/product/label.uvue b/pages/mall/admin/product/labels/index.uvue
similarity index 100%
rename from pages/mall/admin/product/label.uvue
rename to pages/mall/admin/product/labels/index.uvue
diff --git a/pages/mall/admin/product/param.uvue b/pages/mall/admin/product/parameters/index.uvue
similarity index 100%
rename from pages/mall/admin/product/param.uvue
rename to pages/mall/admin/product/parameters/index.uvue
diff --git a/pages/mall/admin/product/product-classification/index.uvue b/pages/mall/admin/product/product-classification/index.uvue
deleted file mode 100644
index 9d71a55a..00000000
--- a/pages/mall/admin/product/product-classification/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product/product-label/index.uvue b/pages/mall/admin/product/product-label/index.uvue
deleted file mode 100644
index 9d71a55a..00000000
--- a/pages/mall/admin/product/product-label/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product/product-param/index.uvue b/pages/mall/admin/product/product-param/index.uvue
deleted file mode 100644
index 9d71a55a..00000000
--- a/pages/mall/admin/product/product-param/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product/product-protection/index.uvue b/pages/mall/admin/product/product-protection/index.uvue
deleted file mode 100644
index ffe3f945..00000000
--- a/pages/mall/admin/product/product-protection/index.uvue
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product/product-reviews/index.uvue b/pages/mall/admin/product/product-reviews/index.uvue
deleted file mode 100644
index 9d71a55a..00000000
--- a/pages/mall/admin/product/product-reviews/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product/product-specifications/index.uvue b/pages/mall/admin/product/product-specifications/index.uvue
deleted file mode 100644
index 3060a6eb..00000000
--- a/pages/mall/admin/product/product-specifications/index.uvue
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/product/product-statistics/index.uvue b/pages/mall/admin/product/product-statistics/index.uvue
index 43b63f5d..27ba9957 100644
--- a/pages/mall/admin/product/product-statistics/index.uvue
+++ b/pages/mall/admin/product/product-statistics/index.uvue
@@ -1,7 +1,8 @@
-
-
-
@@ -274,18 +276,11 @@ function initChart(data: any[]) {
diff --git a/pages/mall/admin/setting/auth/admin.uvue b/pages/mall/admin/setting/auth/admin.uvue
new file mode 100644
index 00000000..a3fe4068
--- /dev/null
+++ b/pages/mall/admin/setting/auth/admin.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 管理员列表 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/auth/permission.uvue b/pages/mall/admin/setting/auth/permission.uvue
new file mode 100644
index 00000000..cb9c5c56
--- /dev/null
+++ b/pages/mall/admin/setting/auth/permission.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 权限设置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/auth/role.uvue b/pages/mall/admin/setting/auth/role.uvue
new file mode 100644
index 00000000..9ebc8c82
--- /dev/null
+++ b/pages/mall/admin/setting/auth/role.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 角色管理 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/delivery/staff.uvue b/pages/mall/admin/setting/delivery/staff.uvue
new file mode 100644
index 00000000..a0dc1ded
--- /dev/null
+++ b/pages/mall/admin/setting/delivery/staff.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 配送员管理 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/delivery/station.uvue b/pages/mall/admin/setting/delivery/station.uvue
new file mode 100644
index 00000000..cb848d40
--- /dev/null
+++ b/pages/mall/admin/setting/delivery/station.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 提货点设置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/delivery/template.uvue b/pages/mall/admin/setting/delivery/template.uvue
new file mode 100644
index 00000000..55733264
--- /dev/null
+++ b/pages/mall/admin/setting/delivery/template.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 运费模板 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/collect.uvue b/pages/mall/admin/setting/interface/collect.uvue
new file mode 100644
index 00000000..aa80b437
--- /dev/null
+++ b/pages/mall/admin/setting/interface/collect.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 商品采集配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/e-sheet.uvue b/pages/mall/admin/setting/interface/e-sheet.uvue
new file mode 100644
index 00000000..5a25a5e2
--- /dev/null
+++ b/pages/mall/admin/setting/interface/e-sheet.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 电子面单配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/logistics.uvue b/pages/mall/admin/setting/interface/logistics.uvue
new file mode 100644
index 00000000..1aacab1c
--- /dev/null
+++ b/pages/mall/admin/setting/interface/logistics.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 物流查询配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/onepass/config.uvue b/pages/mall/admin/setting/interface/onepass/config.uvue
new file mode 100644
index 00000000..b8bd3b6f
--- /dev/null
+++ b/pages/mall/admin/setting/interface/onepass/config.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 一号通配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/onepass/index.uvue b/pages/mall/admin/setting/interface/onepass/index.uvue
new file mode 100644
index 00000000..c0366097
--- /dev/null
+++ b/pages/mall/admin/setting/interface/onepass/index.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 一号通页面 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/payment.uvue b/pages/mall/admin/setting/interface/payment.uvue
new file mode 100644
index 00000000..c27a802e
--- /dev/null
+++ b/pages/mall/admin/setting/interface/payment.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 商城支付配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/sms.uvue b/pages/mall/admin/setting/interface/sms.uvue
new file mode 100644
index 00000000..07e58033
--- /dev/null
+++ b/pages/mall/admin/setting/interface/sms.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 短信接口配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/interface/storage.uvue b/pages/mall/admin/setting/interface/storage.uvue
new file mode 100644
index 00000000..a53f763d
--- /dev/null
+++ b/pages/mall/admin/setting/interface/storage.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 系统存储配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/message.uvue b/pages/mall/admin/setting/message.uvue
new file mode 100644
index 00000000..13442107
--- /dev/null
+++ b/pages/mall/admin/setting/message.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 消息管理 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/system/agreement.uvue b/pages/mall/admin/setting/system/agreement.uvue
new file mode 100644
index 00000000..d6720e55
--- /dev/null
+++ b/pages/mall/admin/setting/system/agreement.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 协议设置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/system/config.uvue b/pages/mall/admin/setting/system/config.uvue
index 8ac661b7..6d9ac126 100644
--- a/pages/mall/admin/setting/system/config.uvue
+++ b/pages/mall/admin/setting/system/config.uvue
@@ -1,81 +1,333 @@
-
-
-
-
-
- 页面占位
- 该功能模块正在开发中
- 当前采用 CRMEB 路由体系 1:1 映射
+
+
+
+
+
+
+
+
+ {{ tab.name }}
+
+
+
+
+
+
+
+
+
+
+
+ 站点开启:
+
+
+
+
+
+ 站点开启/关闭(用于升级等临时关闭),关闭后前端会弹窗显示站点升级中,请稍后访问
+
+
+
+ 网站名称:
+
+
+ 网站名称很多地方会显示的,建议认真填写
+
+
+
+ 网站地址:
+
+
+ 安装自动配置,不要轻易修改,更换后会影响网站访问、接口请求、本地文件储存、支付回调、微信授权、支付、小程序图片访问、部分二维码、官方授权等
+
+
+
+ 消息队列:
+
+
+
+
+
+ 是否启用消息队列,启用后提升程序运行速度,启用前必须配置Redis缓存,文档地址:https://doc.crmeb.com/single/crmeb_v4/7217
+
+
+
+ 联系电话:
+
+
+ 联系电话
+
+
+
+ 授权密钥:
+
+
+
+
+
+
+
+
+
+ 分享图片:
+
+ 上传图片
+ 分享图片比例5:4,建议小于50KB
+
+
+
+ 分享标题:
+
+
+
+
+
+ 分享简介:
+
+
+
+
+
+
+
+
+
+ 后台登录LOGO:
+
+ 上传截图
+ 建议尺寸270*75
+
+
+
+ 后台小LOGO:
+
+ 上传图片
+ 建议尺寸180*180
+
+
+
+ 后台大LOGO:
+
+ 上传图片
+ 建议尺寸170*50
+
+
+
+
+
+
+
+ 移动端JS:
+
+
+
+
+
+ 管理端JS:
+
+
+
+
+
+ PC端JS:
+
+
+
+
+
+
+
+
+
+ 腾讯地图KEY:
+
+
+ 申请地址:https://lbs.qq.com
+
+
+
+
+
+
+
+ 备案号:
+
+
+
+
+
+ ICP链接:
+
+
+
+
+
+
+
+
+
+ 功能开启:
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 远程登录地址:
+
+
+
+
+
+
+
+
+
+ WAF类型:
+
+
+
+
+
+
+ WAF类型:关闭(所有参数都能正常请求),拦截(匹配到WAF配置的参数阻断接口请求),过滤(匹配到WAF配置的参数过滤参数,正常请求接口)
+
+
+
+ WAF配置:
+
+
+ WAF配置验证参数,过滤掉不需要的参数或拦截请求,多个参数用回车换行分隔
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+.waf-textarea { height: 200px; }
+.code-bg { background-color: #f5f7fa; font-family: "Lucida Console", Monaco, monospace; }
+
+.form-tip { font-size: 12px; color: #c0c4cc; margin-top: 8px; line-height: 1.5; width: 550px; }
+
+.radio-group, .checkbox-group { display: flex; flex-direction: row; align-items: center; min-height: 32px; }
+.radio-label, .checkbox-label { display: flex; flex-direction: row; align-items: center; margin-right: 30px; font-size: 14px; color: #606266; cursor: pointer; }
+
+.upload-placeholder { width: 80px; height: 80px; border: 1px dashed #dcdfe6; border-radius: 4px; display: flex; align-items: center; justify-content: center; font-size: 12px; color: #909399; cursor: pointer; transition: all .2s; }
+.upload-placeholder:hover { border-color: #409eff; color: #409eff; }
+
+.submit-section { display: flex; flex-direction: row; margin-top: 20px; padding-top: 10px; }
+.btn-submit { background-color: #1890ff; color: #fff; width: 65px; height: 32px; line-height: 32px; font-size: 14px; border-radius: 4px; margin: 0; border: none; cursor: pointer; text-align: center; }
+.btn-submit:active { background-color: #096dd9; }
+
\ No newline at end of file
diff --git a/pages/mall/admin/setting/system/message.uvue b/pages/mall/admin/setting/system/message.uvue
new file mode 100644
index 00000000..13442107
--- /dev/null
+++ b/pages/mall/admin/setting/system/message.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 消息管理 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/system/ticket.uvue b/pages/mall/admin/setting/system/ticket.uvue
new file mode 100644
index 00000000..c5f02ac2
--- /dev/null
+++ b/pages/mall/admin/setting/system/ticket.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 小票配置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/setting/ticket.uvue b/pages/mall/admin/setting/ticket.uvue
new file mode 100644
index 00000000..5f729ad6
--- /dev/null
+++ b/pages/mall/admin/setting/ticket.uvue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ 客服设置 页面开发中...
+
+
+
+
+
+
+
+
diff --git a/pages/mall/admin/system-settings.uvue b/pages/mall/admin/system-settings.uvue
deleted file mode 100644
index 7a4538e4..00000000
--- a/pages/mall/admin/system-settings.uvue
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/user-management.uvue b/pages/mall/admin/user-management.uvue
deleted file mode 100644
index f170ed1e..00000000
--- a/pages/mall/admin/user-management.uvue
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/user-statistics.uvue b/pages/mall/admin/user-statistics.uvue
deleted file mode 100644
index 143f67ef..00000000
--- a/pages/mall/admin/user-statistics.uvue
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
- 页面参数(query)
- {{ params }}
-
-
-
-
-
-
-
-
diff --git a/pages/mall/admin/user/MemberConfig.uvue b/pages/mall/admin/user/configuration/index.uvue
similarity index 98%
rename from pages/mall/admin/user/MemberConfig.uvue
rename to pages/mall/admin/user/configuration/index.uvue
index 02bed9c3..f563fac0 100644
--- a/pages/mall/admin/user/MemberConfig.uvue
+++ b/pages/mall/admin/user/configuration/index.uvue
@@ -74,7 +74,7 @@
-
+
+
diff --git a/pages/mall/admin/user/group.uvue b/pages/mall/admin/user/grouping/index.uvue
similarity index 100%
rename from pages/mall/admin/user/group.uvue
rename to pages/mall/admin/user/grouping/index.uvue
diff --git a/pages/mall/admin/user/label.uvue b/pages/mall/admin/user/label/index.uvue
similarity index 100%
rename from pages/mall/admin/user/label.uvue
rename to pages/mall/admin/user/label/index.uvue
diff --git a/pages/mall/admin/user/level.uvue b/pages/mall/admin/user/level/index.uvue
similarity index 100%
rename from pages/mall/admin/user/level.uvue
rename to pages/mall/admin/user/level/index.uvue
diff --git a/pages/mall/admin/user/list.uvue b/pages/mall/admin/user/management/index.uvue
similarity index 83%
rename from pages/mall/admin/user/list.uvue
rename to pages/mall/admin/user/management/index.uvue
index 3e094337..bee23ddf 100644
--- a/pages/mall/admin/user/list.uvue
+++ b/pages/mall/admin/user/management/index.uvue
@@ -1,8 +1,9 @@
-
-
-
-
+
+
+
+
+
用户搜索:
@@ -39,7 +40,7 @@
-
+
+
\ No newline at end of file
diff --git a/pages/mall/admin/user/user-grouping/index.uvue b/pages/mall/admin/user/user-grouping/index.uvue
deleted file mode 100644
index 71efde80..00000000
--- a/pages/mall/admin/user/user-grouping/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pages/mall/admin/user/user-label/index.uvue b/pages/mall/admin/user/user-label/index.uvue
deleted file mode 100644
index 056b4908..00000000
--- a/pages/mall/admin/user/user-label/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pages/mall/admin/user/user-level/index.uvue b/pages/mall/admin/user/user-level/index.uvue
deleted file mode 100644
index 3834ce8f..00000000
--- a/pages/mall/admin/user/user-level/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pages/mall/admin/user/user-statistics/index.uvue b/pages/mall/admin/user/user-statistics/index.uvue
deleted file mode 100644
index 27a569a2..00000000
--- a/pages/mall/admin/user/user-statistics/index.uvue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uni_modules/charts/EChartsView.vue b/uni_modules/charts/EChartsView.vue
index 4c321382..fb6c1e24 100644
--- a/uni_modules/charts/EChartsView.vue
+++ b/uni_modules/charts/EChartsView.vue
@@ -31,12 +31,184 @@ const resizeObservers = new Map();
let chinaMapLoaded = false;
let chinaMapLoading = false;
+// 内置的简化中国地图数据(50个主要城市或地区的边界)
+const SIMPLIFIED_CHINA_MAP = {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": { "name": "南海诸岛", "cp": [113.5439, 3.5951], "childNum": 0 },
+ "geometry": { "type": "MultiPolygon", "coordinates": [[[[113.5439, 3.5951], [113.5439, 3.5951]]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "北京", "cp": [116.4074, 39.9042], "childNum": 16 },
+ "geometry": { "type": "Polygon", "coordinates": [[[116, 39.5], [117, 39.5], [117, 40.5], [116, 40.5], [116, 39.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "天津", "cp": [117.2, 39.0842], "childNum": 16 },
+ "geometry": { "type": "Polygon", "coordinates": [[[116.7, 38.7], [117.7, 38.7], [117.7, 39.5], [116.7, 39.5], [116.7, 38.7]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "河北", "cp": [114.5149, 38.0428], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[113.5, 37.5], [119.5, 37.5], [119.5, 42.5], [113.5, 42.5], [113.5, 37.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "山西", "cp": [112.5489, 37.8739], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[110.5, 35], [114.5, 35], [114.5, 40.5], [110.5, 40.5], [110.5, 35]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "内蒙古", "cp": [111.7558, 40.8183], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[97, 37], [126, 37], [126, 54], [97, 54], [97, 37]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "辽宁", "cp": [123.4328, 41.8045], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[118.5, 40], [126.5, 40], [126.5, 45], [118.5, 45], [118.5, 40]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "吉林", "cp": [125.3235, 43.8957], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[121, 41.5], [130, 41.5], [130, 48.5], [121, 48.5], [121, 41.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "黑龙江", "cp": [126.6424, 45.7568], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[121, 43.5], [135, 43.5], [135, 55], [121, 55], [121, 43.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "上海", "cp": [121.4737, 31.2304], "childNum": 16 },
+ "geometry": { "type": "Polygon", "coordinates": [[[120.8, 30.7], [122, 30.7], [122, 31.9], [120.8, 31.9], [120.8, 30.7]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "江苏", "cp": [118.7969, 32.9387], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[118, 31], [122, 31], [122, 34.5], [118, 34.5], [118, 31]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "浙江", "cp": [120.1551, 30.2741], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[118.5, 28], [123, 28], [123, 31.5], [118.5, 31.5], [118.5, 28]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "安徽", "cp": [117.2272, 31.8654], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[114.5, 29.5], [119.5, 29.5], [119.5, 34.5], [114.5, 34.5], [114.5, 29.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "福建", "cp": [119.295492, 26.0745], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[118.5, 23.5], [121.5, 23.5], [121.5, 28], [118.5, 28], [118.5, 23.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "江西", "cp": [115.8581, 28.6832], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[113, 24], [118, 24], [118, 30], [113, 30], [113, 24]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "山东", "cp": [117.1205, 36.6519], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[114, 34.5], [122, 34.5], [122, 38], [114, 38], [114, 34.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "河南", "cp": [113.6254, 34.7466], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[111.5, 32], [117, 32], [117, 36.5], [111.5, 36.5], [111.5, 32]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "湖北", "cp": [114.3055, 30.5928], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[108, 28.5], [116, 28.5], [116, 33], [108, 33], [108, 28.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "湖南", "cp": [112.9388, 28.2282], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[108.5, 24.5], [114, 24.5], [114, 30], [108.5, 30], [108.5, 24.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "广东", "cp": [113.2644, 23.1291], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[112, 20.5], [116, 20.5], [116, 25], [112, 25], [112, 20.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "广西", "cp": [108.3661, 22.8170], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[104.5, 20.5], [112, 20.5], [112, 26.5], [104.5, 26.5], [104.5, 20.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "四川", "cp": [104.0665, 30.5702], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[100, 26], [108, 26], [108, 35], [100, 35], [100, 26]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "贵州", "cp": [106.7135, 26.5783], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[103.5, 24.5], [109.5, 24.5], [109.5, 29.5], [103.5, 29.5], [103.5, 24.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "云南", "cp": [102.7103, 24.8801], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[97.5, 21], [106.5, 21], [106.5, 30], [97.5, 30], [97.5, 21]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "陕西", "cp": [108.9402, 34.3416], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[105.5, 31.5], [111.5, 31.5], [111.5, 39], [105.5, 39], [105.5, 31.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "甘肃", "cp": [103.8343, 35.0080], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[92, 32], [108, 32], [108, 42], [92, 42], [92, 32]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "青海", "cp": [101.7782, 36.6171], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[89, 31.5], [104.5, 31.5], [104.5, 39.5], [89, 39.5], [89, 31.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "宁夏", "cp": [106.2586, 38.4680], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[104.5, 35.5], [107.5, 35.5], [107.5, 40], [104.5, 40], [104.5, 35.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "新疆", "cp": [87.6278, 43.7929], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[73, 26], [104, 26], [104, 49], [73, 49], [73, 26]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "西藏", "cp": [88.0959, 29.6470], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[78, 26], [99, 26], [99, 36.5], [78, 36.5], [78, 26]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "台湾", "cp": [120.9605, 23.6978], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[120.1, 22.5], [121.5, 22.5], [121.5, 25], [120.1, 25], [120.1, 22.5]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "香港", "cp": [114.1694, 22.3193], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[113.8, 22], [114.5, 22], [114.5, 22.6], [113.8, 22.6], [113.8, 22]]] }
+ },
+ {
+ "type": "Feature",
+ "properties": { "name": "澳门", "cp": [113.5439, 22.2987], "childNum": 0 },
+ "geometry": { "type": "Polygon", "coordinates": [[[113.3, 22.1], [113.7, 22.1], [113.7, 22.5], [113.3, 22.5], [113.3, 22.1]]] }
+ }
+ ]
+};
+
// 加载并注册中国地图
async function loadChinaMap() {
if (chinaMapLoaded) {
return Promise.resolve();
}
-
+
if (chinaMapLoading) {
// 如果正在加载,等待加载完成
return new Promise((resolve) => {
@@ -53,32 +225,67 @@ async function loadChinaMap() {
}, 10000);
});
}
-
+
chinaMapLoading = true;
-
+
try {
- // 从在线 CDN 加载中国地图 GeoJSON 数据
- // 使用 ECharts 官方示例数据源
- const response = await fetch('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json');
- if (!response.ok) {
- // 如果第一个源失败,尝试备用源
- const backupResponse = await fetch('https://echarts.apache.org/examples/data/map/china.json');
- if (!backupResponse.ok) {
- throw new Error('Failed to load China map data');
+ // 首先尝试从在线 CDN 加载中国地图 GeoJSON 数据
+ let geoJson = null;
+ let loaded = false;
+
+ try {
+ const response = await fetch('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json', {
+ timeout: 5000
+ });
+ if (response.ok) {
+ geoJson = await response.json();
+ loaded = true;
+ console.log('[EChartsView] 从阿里云 CDN 加载中国地图数据成功');
}
- const geoJson = await backupResponse.json();
- echarts.registerMap('china', geoJson);
- } else {
- const geoJson = await response.json();
- echarts.registerMap('china', geoJson);
+ } catch (e) {
+ console.warn('[EChartsView] 从阿里云 CDN 加载失败,尝试备用源...', e);
+ }
+
+ // 如果第一个源失败,尝试备用源
+ if (!loaded) {
+ try {
+ const backupResponse = await fetch('https://echarts.apache.org/examples/data/map/china.json', {
+ timeout: 5000
+ });
+ if (backupResponse.ok) {
+ geoJson = await backupResponse.json();
+ loaded = true;
+ console.log('[EChartsView] 从 ECharts 官方源加载中国地图数据成功');
+ }
+ } catch (e) {
+ console.warn('[EChartsView] 从备用源加载也失败,使用内置简化地图', e);
+ }
+ }
+
+ // 如果网络加载都失败,使用内置的简化地图
+ if (!loaded) {
+ geoJson = SIMPLIFIED_CHINA_MAP;
+ console.log('[EChartsView] 使用内置简化中国地图数据');
+ }
+
+ // 注册地图
+ if (geoJson) {
+ echarts.registerMap('china', geoJson);
+ chinaMapLoaded = true;
+ console.log('[EChartsView] 中国地图数据已注册');
+ } else {
+ throw new Error('Failed to load or create China map data');
}
-
- chinaMapLoaded = true;
- console.log('[EChartsView] 中国地图数据已加载并注册');
} catch (error) {
console.error('[EChartsView] 加载中国地图数据失败:', error);
- // 即使加载失败,也标记为已尝试,避免重复请求
- chinaMapLoaded = false;
+ // 降级方案:使用简化地图
+ try {
+ echarts.registerMap('china', SIMPLIFIED_CHINA_MAP);
+ chinaMapLoaded = true;
+ console.log('[EChartsView] 已使用内置简化地图作为降级方案');
+ } catch (furtherError) {
+ console.error('[EChartsView] 即使使用简化地图也失败:', furtherError);
+ }
} finally {
chinaMapLoading = false;
}
@@ -94,15 +301,15 @@ function getChartKey(el) {
function ensureChart(el, retryCount = 0) {
if (!el) return null;
-
+
const key = getChartKey(el);
let chart = charts.get(key);
-
+
// 如果图表已存在且有效,直接返回
if (chart && !chart.isDisposed()) {
return chart;
}
-
+
// 如果图表已销毁,从 Map 中移除
if (chart && chart.isDisposed()) {
charts.delete(key);
@@ -113,19 +320,19 @@ function ensureChart(el, retryCount = 0) {
}
chart = null;
}
-
+
// 确保元素有尺寸
const rect = el.getBoundingClientRect();
const computedStyle = window.getComputedStyle(el);
const width = parseFloat(computedStyle.width) || rect.width;
const height = parseFloat(computedStyle.height) || rect.height;
-
+
// 如果尺寸为 0,尝试延迟初始化(最多重试 10 次)
if ((width === 0 || height === 0) && retryCount < 10) {
if (retryCount === 0) {
console.warn('[EChartsView] 容器尺寸为 0,延迟初始化', { width, height, rect });
}
-
+
// 使用指数退避策略,避免无限循环
const delay = Math.min(100 * Math.pow(1.5, retryCount), 1000);
setTimeout(() => {
@@ -133,7 +340,7 @@ function ensureChart(el, retryCount = 0) {
}, delay);
return null;
}
-
+
// 如果重试次数过多,使用默认尺寸
if (width === 0 || height === 0) {
console.warn('[EChartsView] 容器尺寸仍为 0,使用默认尺寸', { width, height });
@@ -141,7 +348,7 @@ function ensureChart(el, retryCount = 0) {
const parentRect = el.parentElement ? el.parentElement.getBoundingClientRect() : { width: 800, height: 400 };
const finalWidth = width || parentRect.width || 800;
const finalHeight = height || parentRect.height || 400;
-
+
if (finalWidth > 0 && finalHeight > 0) {
// 设置元素尺寸
el.style.width = finalWidth + 'px';
@@ -151,19 +358,19 @@ function ensureChart(el, retryCount = 0) {
return null;
}
}
-
+
try {
// 注意:地图数据加载在 setOption 中处理,这里不处理
// 因为 ensureChart 是同步函数,不能使用 await
-
- chart = echarts.init(el, null, {
+
+ chart = echarts.init(el, null, {
renderer: "canvas",
width: rect.width,
height: rect.height
});
-
+
charts.set(key, chart);
-
+
// 自适应:监听容器尺寸变化
if (typeof ResizeObserver !== "undefined") {
const ro = new ResizeObserver((entries) => {
@@ -200,7 +407,7 @@ function ensureChart(el, retryCount = 0) {
// 存储 handler 以便后续清理
el._resizeHandler = resizeHandler;
}
-
+
return chart;
} catch (e) {
console.error('[EChartsView] 初始化失败', e);
@@ -212,7 +419,7 @@ function disposeChart(el) {
if (!el) return;
const key = getChartKey(el);
const chart = charts.get(key);
-
+
if (chart && !chart.isDisposed()) {
try {
chart.dispose();
@@ -220,15 +427,15 @@ function disposeChart(el) {
console.warn('[EChartsView] dispose 失败', e);
}
}
-
+
charts.delete(key);
-
+
const ro = resizeObservers.get(key);
if (ro) {
ro.disconnect();
resizeObservers.delete(key);
}
-
+
if (el._resizeHandler) {
window.removeEventListener("resize", el._resizeHandler);
delete el._resizeHandler;
@@ -260,22 +467,22 @@ export default {
console.error('[EChartsView] setOption: 找不到容器元素');
return;
}
-
+
// 检查 option 是否有效
if (!option || typeof option !== 'object') {
console.warn('[EChartsView] setOption: option 无效', option);
return;
}
-
+
// 检查是否使用了地图,如果是,先加载地图数据
const needsMap = option.geo || (option.series && Array.isArray(option.series) && option.series.some(s => s.type === 'map' && s.map === 'china'));
if (needsMap) {
await loadChinaMap();
}
-
+
// 保存 option 供 ensureChart 使用
el._pendingOption = option;
-
+
// 确保图表已初始化
let c = ensureChart(el);
if (!c) {
@@ -369,7 +576,7 @@ export default {
}
return;
}
-
+
// 检查图表是否已销毁
if (c.isDisposed()) {
console.warn('[EChartsView] setOption: 图表已销毁,重新初始化');
@@ -380,7 +587,7 @@ export default {
c = ensureChart(el);
if (!c) return;
}
-
+
try {
// 如果使用地图,确保地图已加载
if (needsMap) {
@@ -389,7 +596,7 @@ export default {
// 深拷贝 option 确保是纯 JS 对象
const plainOption = JSON.parse(JSON.stringify(option));
c.setOption(plainOption, true);
-
+
// 使用 requestAnimationFrame 避免 resize 警告
requestAnimationFrame(() => {
const key = getChartKey(el);
@@ -415,11 +622,20 @@ export default {
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 00000000..86a6425a
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,12 @@
+import { defineConfig } from 'vite'
+import { fileURLToPath, URL } from 'node:url'
+import uni from '@dcloudio/vite-plugin-uni'
+
+export default defineConfig({
+ plugins: [uni()],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./', import.meta.url))
+ }
+ }
+})