From c0d139651caea246f14c515e645c8c3971c5d9b5 Mon Sep 17 00:00:00 2001 From: gpu Date: Sun, 4 Jan 2026 10:14:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...°ç®¡ç†ç³»ç»Ÿ-业务模å—è¿ç§»æ¸…å•.md | 371 ++++++++++++++++++ .../src/layout/components/Header.vue | 23 +- .../src/layout/components/Sidebar.vue | 60 ++- .../admin-web/src/layout/index.vue | 13 +- .../admin-web/src/styles/index.css | 45 ++- .../admin-web/src/styles/variables.css | 116 ++++++ .../admin-web/src/views/dashboard/index.vue | 49 ++- .../admin-web/src/views/login/index.vue | 61 ++- 8 files changed, 701 insertions(+), 37 deletions(-) create mode 100644 docs/åŽå°ç®¡ç†ç³»ç»Ÿ-业务模å—è¿ç§»æ¸…å•.md create mode 100644 server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/variables.css diff --git a/docs/åŽå°ç®¡ç†ç³»ç»Ÿ-业务模å—è¿ç§»æ¸…å•.md b/docs/åŽå°ç®¡ç†ç³»ç»Ÿ-业务模å—è¿ç§»æ¸…å•.md new file mode 100644 index 00000000..43029373 --- /dev/null +++ b/docs/åŽå°ç®¡ç†ç³»ç»Ÿ-业务模å—è¿ç§»æ¸…å•.md @@ -0,0 +1,371 @@ +# HoneyBox åŽå°ç®¡ç†ç³»ç»Ÿ - 业务模å—è¿ç§»æ¸…å• + +## è¿ç§»æ¦‚è¿° + +本文档列出了从 PHP (ThinkPHP 6.0) åŽå°è¿ç§»åˆ° ASP.NET Core 的所有业务模å—。 +基础æƒé™æ¡†æž¶ï¼ˆç™»å½•ã€èœå•ã€è§’è‰²ã€æƒé™ã€éƒ¨é—¨ï¼‰å·²å®Œæˆï¼ŒçŽ°è¿›å…¥ä¸šåŠ¡æ¨¡å—è¿ç§»é˜¶æ®µã€‚ + +--- + +## ä¸€ã€æ¨¡å—优先级分类 + +### P0 - 核心业务模å—(必须优先è¿ç§»ï¼‰ + +| åºå· | 模å—åç§° | PHP 控制器 | 功能说明 | 预计工时 | +|------|----------|-----------|----------|----------| +| 1 | 首页仪表盘 | Index.php | æ•°æ®ç»Ÿè®¡æ¦‚览ã€ä»Šæ—¥æ•°æ®ã€è¶‹åŠ¿å›¾è¡¨ | 1天 | +| 2 | ç”¨æˆ·ç®¡ç† | User.php | 用户列表ã€å°ç¦/è§£å°ã€èµ„金å˜åЍã€VIP管ç†ã€ä¸‹çº§ç”¨æˆ· | 3天 | +| 3 | 商å“ç®¡ç† | Goods.php, GoodsType.php | ç›’å­ç®¡ç†ã€å¥–å“é…ç½®ã€åº“存管ç†ã€9ç§ç›’å­ç±»åž‹ | 4天 | +| 4 | 订å•ç®¡ç† | Order.php | 订å•列表ã€å¡å•处ç†ã€å‘货管ç†ã€é€€æ¬¾ã€å¯¼å‡º | 3天 | + +### P1 - é‡è¦ä¸šåŠ¡æ¨¡å— + +| åºå· | 模å—åç§° | PHP 控制器 | 功能说明 | 预计工时 | +|------|----------|-----------|----------|----------| +| 5 | è´¢åŠ¡ç®¡ç† | Finance.php | 消费排行ã€ä½™é¢æ˜Žç»†ã€ç§¯åˆ†æ˜Žç»†ã€å……值记录 | 2天 | +| 6 | æçŽ°ç®¡ç† | Withdraw.php | æçŽ°ç”³è¯·åˆ—è¡¨ã€å®¡æ ¸ã€æ‰“款 | 1天 | +| 7 | 抽奖é…ç½® | Draw.php, Cardextractor.php | 抽奖活动é…ç½®ã€æŠ½å¡æœºé…ç½® | 2天 | +| 8 | 系统é…ç½® | Config.php | 支付é…ç½®ã€ä¸Šä¼ é…ç½®ã€ç³»ç»Ÿå‚æ•° | 1天 | + +### P2 - è¥é”€ä¸Žå†…å®¹æ¨¡å— + +| åºå· | 模å—åç§° | PHP 控制器 | 功能说明 | 预计工时 | +|------|----------|-----------|----------|----------| +| 9 | ä¼˜æƒ åˆ¸ç®¡ç† | Coupon.php, CouponReceive.php | 优惠券创建ã€å‘放ã€é¢†å–记录 | 2天 | +| 10 | å¥–åŠ±ç®¡ç† | Reward.php | 奖励é…ç½®ã€å‘放规则 | 1天 | +| 11 | æŽ’è¡Œæ¦œç®¡ç† | Rank.php, UserRank.php | 排行榜é…ç½®ã€ç”¨æˆ·æŽ’å | 1天 | +| 12 | å¹¿å‘Šç®¡ç† | Advert.php, AdvertType.php | 广告ä½ç®¡ç†ã€å¹¿å‘ŠæŠ•æ”¾ | 1天 | +| 13 | å•é¡µç®¡ç† | Danye.php | 陿€é¡µé¢ç®¡ç†ï¼ˆå…³äºŽæˆ‘们ã€å议等) | 0.5天 | +| 14 | å…¬å‘Šç®¡ç† | NewsController.php | ç³»ç»Ÿå…¬å‘Šã€æ¶ˆæ¯æŽ¨é€ | 0.5天 | + +### P3 - è¾…åŠ©åŠŸèƒ½æ¨¡å— + +| åºå· | 模å—åç§° | PHP 控制器 | 功能说明 | 预计工时 | +|------|----------|-----------|----------|----------| +| 15 | 统计报表 | Statistics.php | æ•°æ®åˆ†æžã€æŠ¥è¡¨å¯¼å‡º | 2天 | +| 16 | 签到é…ç½® | SignConfig.php | 签到奖励é…ç½® | 0.5天 | +| 17 | ä»»åŠ¡ç®¡ç† | TaskList.php | 任务é…ç½®ã€å®Œæˆå¥–励 | 1天 | +| 18 | ç¦åˆ©å±‹ | WelfareHouse.php | ç¦åˆ©æ´»åŠ¨ç®¡ç† | 1天 | +| 19 | ç§’æ€ç®¡ç† | Seckill.php | ç§’æ€æ´»åЍé…ç½® | 1天 | +| 20 | é’»çŸ³ç®¡ç† | Diamond.php | 钻石充值é…ç½® | 0.5天 | +| 21 | æ‚¬æµ®çƒ | FloatBall.php | 悬浮çƒé…ç½® | 0.5天 | +| 22 | 文件上传 | Upload.php, Upload2.php | 文件上传æœåŠ¡ | 0.5天 | + +--- + +## 二ã€è¯¦ç»†æ¨¡å—说明 + +### 2.1 首页仪表盘 (Index) + +**功能清å•:** +- 今日注册用户数 +- ä»Šæ—¥æ¶ˆè´¹é‡‘é¢ +- ä»Šæ—¥è®¢å•æ•° +- 总用户数/æ€»è®¢å•æ•°/总收入 +- è¿‘7天/30天趋势图 +- 广告数æ®ç»Ÿè®¡ + +**API 设计:** +``` +GET /api/admin/dashboard/overview # æ¦‚è§ˆæ•°æ® +GET /api/admin/dashboard/trend # è¶‹åŠ¿æ•°æ® +GET /api/admin/dashboard/ads # 广告统计 +``` + +--- + +### 2.2 ç”¨æˆ·ç®¡ç† (User) + +**功能清å•:** +- ç”¨æˆ·åˆ—è¡¨ï¼ˆåˆ†é¡µã€æœç´¢ã€ç­›é€‰ï¼‰ +- 用户详情(基本信æ¯ã€æ¶ˆè´¹ç»Ÿè®¡ã€ç›’柜价值) +- 资金å˜åŠ¨ï¼ˆä½™é¢ã€ç§¯åˆ†ã€é’»çŸ³ï¼‰ +- å°å·/è§£å° +- 清空手机å·/微信绑定 +- è®¾ç½®æµ‹è¯•è´¦å· +- èµ é€ä¼˜æƒ åˆ¸/å¡ç‰Œ +- VIP ç­‰çº§ç®¡ç† +- 用户盈äºç»Ÿè®¡ +- 下级用户列表 +- æµæ°´æ˜Žç»† + +**API 设计:** +``` +GET /api/admin/business/users # 用户列表 +GET /api/admin/business/users/{id} # 用户详情 +PUT /api/admin/business/users/{id}/status # å°å·/è§£å° +PUT /api/admin/business/users/{id}/money # 资金å˜åЍ +PUT /api/admin/business/users/{id}/test # è®¾ç½®æµ‹è¯•è´¦å· +DELETE /api/admin/business/users/{id}/mobile # æ¸…ç©ºæ‰‹æœºå· +DELETE /api/admin/business/users/{id}/wechat # 清空微信绑定 +POST /api/admin/business/users/{id}/coupon # èµ é€ä¼˜æƒ åˆ¸ +POST /api/admin/business/users/{id}/card # èµ é€å¡ç‰Œ +GET /api/admin/business/users/{id}/team # 下级用户 +GET /api/admin/business/users/{id}/profit # 盈äºç»Ÿè®¡ +GET /api/admin/business/vip # VIP等级列表 +PUT /api/admin/business/vip/{id} # 编辑VIP等级 +``` + +--- + +### 2.3 商å“ç®¡ç† (Goods) + +**功能清å•:** +- ç›’å­åˆ—表(9ç§ç±»åž‹ï¼šä¸€ç•ªèµã€æ— é™èµã€æ“‚å°èµã€æŠ½å¡æœºã€ç¦è¢‹ã€å¹¸è¿èµã€ç›²ç›’ã€æ‰­è›‹ã€ç¦åˆ©å±‹ï¼‰ +- ç›’å­æ–°å¢ž/编辑/删除 +- ç›’å­ä¸Šæž¶/下架 +- 奖å“管ç†ï¼ˆæ·»åŠ ã€ç¼–辑ã€åˆ é™¤ã€åº“存调整) +- 奖å“等级é…ç½® +- ç›’å­ç±»åž‹ç®¡ç† +- ç›’å­æ‰©å±•ä¿¡æ¯ +- 商å“åˆ†ç±»ç®¡ç† + +**API 设计:** +``` +GET /api/admin/business/goods # ç›’å­åˆ—表 +GET /api/admin/business/goods/{id} # ç›’å­è¯¦æƒ… +POST /api/admin/business/goods # æ–°å¢žç›’å­ +PUT /api/admin/business/goods/{id} # ç¼–è¾‘ç›’å­ +DELETE /api/admin/business/goods/{id} # åˆ é™¤ç›’å­ +PUT /api/admin/business/goods/{id}/status # 上架/下架 +GET /api/admin/business/goods/{id}/prizes # 奖å“列表 +POST /api/admin/business/goods/{id}/prizes # æ·»åŠ å¥–å“ +PUT /api/admin/business/goods/prizes/{id} # ç¼–è¾‘å¥–å“ +DELETE /api/admin/business/goods/prizes/{id} # åˆ é™¤å¥–å“ +GET /api/admin/business/goods-types # ç›’å­ç±»åž‹åˆ—表 +GET /api/admin/business/prize-levels # 奖å“等级列表 +``` + +--- + +### 2.4 订å•ç®¡ç† (Order) + +**功能清å•:** +- 购买订å•列表 +- å¡å•列表(支付æˆåŠŸä½†æœªå‘奖) +- 订å•è¯¦æƒ…ï¼ˆå¥–å“æ˜Žç»†ï¼‰ +- å…‘æ¢è®¢å•列表(回收) +- å‘货订å•列表 +- å‘货处ç†ï¼ˆå•个/批é‡ï¼‰ +- 订å•导出(Excel) +- 物æµä¿¡æ¯æŸ¥è¯¢ + +**API 设计:** +``` +GET /api/admin/business/orders # 订å•列表 +GET /api/admin/business/orders/{id} # 订å•详情 +GET /api/admin/business/orders/stuck # å¡å•列表 +POST /api/admin/business/orders/{id}/retry # é‡è¯•å‘奖 +GET /api/admin/business/orders/recovery # å…‘æ¢è®¢å• +GET /api/admin/business/orders/shipping # å‘è´§è®¢å• +PUT /api/admin/business/orders/{id}/ship # å‘è´§å¤„ç† +POST /api/admin/business/orders/batch-ship # 批é‡å‘è´§ +GET /api/admin/business/orders/export # å¯¼å‡ºè®¢å• +``` + +--- + +### 2.5 è´¢åŠ¡ç®¡ç† (Finance) + +**功能清å•:** +- 消费排行榜 +- 余颿˜Žç»†ï¼ˆå……å€¼ã€æ¶ˆè´¹ã€æçŽ°ï¼‰ +- 积分明细 +- 钻石明细 +- 充值记录 +- 微信支付日志 + +**API 设计:** +``` +GET /api/admin/business/finance/ranking # 消费排行 +GET /api/admin/business/finance/money # 余颿˜Žç»† +GET /api/admin/business/finance/integral # 积分明细 +GET /api/admin/business/finance/diamond # 钻石明细 +GET /api/admin/business/finance/recharge # 充值记录 +GET /api/admin/business/finance/wxpay-logs # 微信支付日志 +``` + +--- + +### 2.6 æçŽ°ç®¡ç† (Withdraw) + +**功能清å•:** +- æçŽ°ç”³è¯·åˆ—è¡¨ +- æçŽ°å®¡æ ¸ï¼ˆé€šè¿‡/æ‹’ç»ï¼‰ +- æçŽ°æ‰“æ¬¾ï¼ˆå¾®ä¿¡ä¼ä¸šä»˜æ¬¾ï¼‰ +- æçŽ°è®°å½•æŸ¥è¯¢ + +**API 设计:** +``` +GET /api/admin/business/withdraws # æçŽ°åˆ—è¡¨ +PUT /api/admin/business/withdraws/{id}/audit # 审核 +POST /api/admin/business/withdraws/{id}/pay # 打款 +``` + +--- + +### 2.7 抽奖é…ç½® (Draw, Cardextractor) + +**功能清å•:** +- 抽奖活动列表 +- 抽奖活动é…ç½® +- æŠ½å¡æœºé…ç½® +- å¡ç‰Œå•†å“ç®¡ç† + +**API 设计:** +``` +GET /api/admin/business/draws # 抽奖活动列表 +POST /api/admin/business/draws # 新增活动 +PUT /api/admin/business/draws/{id} # 编辑活动 +DELETE /api/admin/business/draws/{id} # 删除活动 +GET /api/admin/business/card-extractors # æŠ½å¡æœºåˆ—表 +POST /api/admin/business/card-extractors # æ–°å¢žæŠ½å¡æœº +PUT /api/admin/business/card-extractors/{id} +DELETE /api/admin/business/card-extractors/{id} +``` + +--- + +### 2.8 系统é…ç½® (Config) + +**功能清å•:** +- 支付é…ç½®ï¼ˆå¾®ä¿¡æ”¯ä»˜å‚æ•°ï¼‰ +- 上传é…置(腾讯云COS) +- ç³»ç»Ÿå‚æ•°ï¼ˆç«™ç‚¹åç§°ã€å®¢æœç­‰ï¼‰ +- 短信é…ç½® +- 分享é…ç½® + +**API 设计:** +``` +GET /api/admin/business/config/{group} # 获å–é…置组 +PUT /api/admin/business/config/{group} # æ›´æ–°é…置组 +``` + +--- + +## ä¸‰ã€æ•°æ®åº“表映射 + +业务模å—需è¦è®¿é—® `honey_box` 业务数æ®åº“ï¼Œä¸»è¦æ¶‰åŠä»¥ä¸‹è¡¨ï¼š + +| 业务表 | 说明 | å¯¹åº”æ¨¡å— | +|--------|------|----------| +| users | 用户表 | ç”¨æˆ·ç®¡ç† | +| user_account | 用户账户扩展 | ç”¨æˆ·ç®¡ç† | +| user_vip | VIP等级é…ç½® | ç”¨æˆ·ç®¡ç† | +| goods | ç›’å­è¡¨ | 商å“ç®¡ç† | +| goods_list | 奖å“表 | 商å“ç®¡ç† | +| goods_type | ç›’å­ç±»åž‹ | 商å“ç®¡ç† | +| goods_extend | ç›’å­æ‰©å±•ä¿¡æ¯ | 商å“ç®¡ç† | +| shang | 奖å“等级 | 商å“ç®¡ç† | +| order | 订å•表 | 订å•ç®¡ç† | +| order_list | 订å•奖哿˜Žç»† | 订å•ç®¡ç† | +| order_list_send | å‘货记录 | 订å•ç®¡ç† | +| profit_money | 余颿µæ°´ | è´¢åŠ¡ç®¡ç† | +| profit_integral | ç§¯åˆ†æµæ°´ | è´¢åŠ¡ç®¡ç† | +| profit_money2 | é’»çŸ³æµæ°´ | è´¢åŠ¡ç®¡ç† | +| user_recharge | 充值记录 | è´¢åŠ¡ç®¡ç† | +| withdraw | æçŽ°è®°å½• | æçŽ°ç®¡ç† | +| coupon | 优惠券 | ä¼˜æƒ åˆ¸ç®¡ç† | +| coupon_receive | ä¼˜æƒ åˆ¸é¢†å– | ä¼˜æƒ åˆ¸ç®¡ç† | +| advert | 广告 | å¹¿å‘Šç®¡ç† | +| advert_type | 广告类型 | å¹¿å‘Šç®¡ç† | +| config | 系统é…ç½® | 系统é…ç½® | + +--- + +## å››ã€æŠ€æœ¯å®žçŽ°è¦ç‚¹ + +### 4.1 跨库查询 + +HoneyBox.Admin 需è¦åŒæ—¶è®¿é—®ä¸¤ä¸ªæ•°æ®åº“: +- `honey_box_admin` - åŽå°ç®¡ç†æ•°æ®ï¼ˆç®¡ç†å‘˜ã€è§’色ã€èœå•等) +- `honey_box` - 业务数æ®ï¼ˆç”¨æˆ·ã€å•†å“ã€è®¢å•等) + +**实现方案:** +```csharp +// 在 HoneyBox.Admin 中引用 HoneyBox.Model +// 注入两个 DbContext +services.AddDbContext(options => + options.UseSqlServer(adminConnectionString)); +services.AddDbContext(options => + options.UseSqlServer(businessConnectionString)); +``` + +### 4.2 业务æœåС层 + +在 `HoneyBox.Admin/Services/Business/` 下创建业务æœåŠ¡ï¼š +- UserBusinessService - 用户业务æœåŠ¡ +- GoodsBusinessService - 商å“业务æœåŠ¡ +- OrderBusinessService - 订å•业务æœåŠ¡ +- FinanceBusinessService - 财务业务æœåŠ¡ + +### 4.3 控制器组织 + +在 `HoneyBox.Admin/Controllers/Business/` 下创建业务控制器: +``` +Controllers/ +├── AuthController.cs # 认è¯ï¼ˆå·²å®Œæˆï¼‰ +├── MenuController.cs # èœå•(已完æˆï¼‰ +├── RoleController.cs # 角色(已完æˆï¼‰ +├── AdminUserController.cs # 管ç†å‘˜ï¼ˆå·²å®Œæˆï¼‰ +├── DepartmentController.cs # 部门(已完æˆï¼‰ +├── PermissionController.cs # æƒé™ï¼ˆå·²å®Œæˆï¼‰ +├── OperationLogController.cs # æ“作日志(已完æˆï¼‰ +└── Business/ # 业务模å—(待è¿ç§»ï¼‰ + ├── DashboardController.cs # 仪表盘 + ├── UserController.cs # ç”¨æˆ·ç®¡ç† + ├── GoodsController.cs # 商å“ç®¡ç† + ├── OrderController.cs # 订å•ç®¡ç† + ├── FinanceController.cs # è´¢åŠ¡ç®¡ç† + ├── WithdrawController.cs # æçŽ°ç®¡ç† + ├── CouponController.cs # ä¼˜æƒ åˆ¸ç®¡ç† + └── ConfigController.cs # 系统é…ç½® +``` + +--- + +## 五ã€å‰ç«¯é¡µé¢æ¸…å• + +### 5.1 éœ€è¦æ–°å¢žçš„å‰ç«¯é¡µé¢ + +| 页é¢è·¯å¾„ | 页é¢åç§° | 对应åŽç«¯æ¨¡å— | +|----------|----------|--------------| +| /dashboard | 仪表盘 | Dashboard | +| /business/user | ç”¨æˆ·ç®¡ç† | User | +| /business/user/vip | VIPç®¡ç† | User | +| /business/goods | 商å“ç®¡ç† | Goods | +| /business/goods/type | ç›’å­ç±»åž‹ | Goods | +| /business/goods/prize | 奖å“ç®¡ç† | Goods | +| /business/order | 订å•ç®¡ç† | Order | +| /business/order/shipping | å‘è´§ç®¡ç† | Order | +| /business/finance | è´¢åŠ¡ç®¡ç† | Finance | +| /business/withdraw | æçŽ°ç®¡ç† | Withdraw | +| /business/coupon | ä¼˜æƒ åˆ¸ç®¡ç† | Coupon | +| /business/advert | å¹¿å‘Šç®¡ç† | Advert | +| /business/config | 系统é…ç½® | Config | + +--- + +## å…­ã€è¿ç§»è®¡åˆ’时间表 + +| 阶段 | æ¨¡å— | 预计工时 | å»ºè®®é¡ºåº | +|------|------|----------|----------| +| 第1周 | 首页仪表盘 + ç”¨æˆ·ç®¡ç† | 4天 | 1 | +| 第2周 | 商å“ç®¡ç† | 4天 | 2 | +| 第3周 | 订å•ç®¡ç† + è´¢åŠ¡ç®¡ç† | 5天 | 3 | +| 第4周 | æçŽ°ç®¡ç† + 系统é…ç½® + 抽奖é…ç½® | 4天 | 4 | +| 第5周 | 优惠券 + 广告 + å…¶ä»–è¥é”€æ¨¡å— | 5天 | 5 | +| 第6周 | 统计报表 + å‰©ä½™è¾…åŠ©æ¨¡å— | 5天 | 6 | + +**总预计工时:约 27 天(6周)** + +--- + +## 七ã€ä¸‹ä¸€æ­¥è¡ŒåЍ + +1. **确认本清å•** - 确认模å—优先级和è¿ç§»é¡ºåº +2. **创建业务控制器目录** - `Controllers/Business/` +3. **é…置跨库访问** - 引用 HoneyBox.Model,注入 HoneyBoxDbContext +4. **开始 P0 模å—è¿ç§»** - 从仪表盘和用户管ç†å¼€å§‹ + +确认åŽå¯ä»¥å¼€å§‹åˆ›å»ºè¯¦ç»†çš„实现任务清å•。 diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Header.vue b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Header.vue index 54647664..a9b444d4 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Header.vue +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Header.vue @@ -92,6 +92,7 @@ const handleCommand = async (command: string) => { display: flex; align-items: center; justify-content: space-between; + background-color: var(--header-bg); } .header-left { @@ -103,11 +104,12 @@ const handleCommand = async (command: string) => { .collapse-btn { font-size: 20px; cursor: pointer; - color: #606266; + color: var(--text-regular); + transition: color var(--transition-duration) var(--transition-timing); } .collapse-btn:hover { - color: #409eff; + color: var(--primary-color); } .header-right { @@ -120,9 +122,24 @@ const handleCommand = async (command: string) => { align-items: center; gap: 8px; cursor: pointer; + padding: 6px 12px; + border-radius: var(--border-radius-base); + transition: background-color var(--transition-duration) var(--transition-timing); +} + +.user-info:hover { + background-color: var(--bg-hover); } .username { - color: #606266; + color: var(--text-regular); +} + +:deep(.el-breadcrumb__inner) { + color: var(--text-secondary); +} + +:deep(.el-breadcrumb__item:last-child .el-breadcrumb__inner) { + color: var(--text-primary); } diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Sidebar.vue b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Sidebar.vue index 7ecb0e8a..f8eadd3d 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Sidebar.vue +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/components/Sidebar.vue @@ -9,9 +9,10 @@ :default-active="activeMenu" :collapse="collapse" :unique-opened="true" - background-color="#304156" - text-color="#bfcbd9" - active-text-color="#409eff" + background-color="transparent" + text-color="var(--sidebar-text)" + active-text-color="var(--sidebar-text-active)" + class="sidebar-menu" router > route.path) height: 100%; display: flex; flex-direction: column; + background-color: var(--sidebar-bg); } .sidebar-logo { @@ -53,26 +55,66 @@ const activeMenu = computed(() => route.path) display: flex; align-items: center; justify-content: center; - background-color: #263445; + background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%); } .logo-title { - color: #fff; + color: var(--text-white); + font-size: 18px; + font-weight: bold; + letter-spacing: 1px; +} + +.logo-title-mini { + color: var(--text-white); font-size: 18px; font-weight: bold; } -.logo-title-mini { - color: #fff; - font-size: 18px; - font-weight: bold; +.sidebar-menu { + border-right: none !important; } :deep(.el-menu) { border-right: none; + background-color: transparent !important; } :deep(.el-menu--collapse) { width: 64px; } + +:deep(.el-menu-item) { + margin: 4px 8px; + border-radius: var(--border-radius-base); + transition: all var(--transition-duration) var(--transition-timing); +} + +:deep(.el-menu-item:hover) { + background-color: var(--sidebar-item-hover) !important; +} + +:deep(.el-menu-item.is-active) { + background-color: var(--sidebar-item-active) !important; + color: var(--sidebar-text-active) !important; + font-weight: 500; +} + +:deep(.el-sub-menu__title) { + margin: 4px 8px; + border-radius: var(--border-radius-base); + transition: all var(--transition-duration) var(--transition-timing); +} + +:deep(.el-sub-menu__title:hover) { + background-color: var(--sidebar-item-hover) !important; +} + +:deep(.el-sub-menu .el-menu) { + background-color: transparent !important; +} + +:deep(.el-sub-menu .el-menu-item) { + margin: 2px 8px 2px 16px; +} diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/index.vue b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/index.vue index b35ea980..02478fe6 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/index.vue +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/layout/index.vue @@ -49,9 +49,10 @@ const toggleCollapse = () => { } .layout-aside { - background-color: #304156; - transition: width 0.3s; + background-color: var(--sidebar-bg); + transition: width var(--transition-duration) var(--transition-timing); overflow: hidden; + border-right: 1px solid var(--border-lighter); } .layout-main { @@ -60,10 +61,10 @@ const toggleCollapse = () => { } .layout-header { - height: 50px; + height: var(--header-height); padding: 0; - background-color: #fff; - box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); + background-color: var(--header-bg); + box-shadow: var(--header-shadow); display: flex; align-items: center; } @@ -71,7 +72,7 @@ const toggleCollapse = () => { .layout-content { flex: 1; padding: 20px; - background-color: #f0f2f5; + background-color: var(--bg-page); overflow: auto; } diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/index.css b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/index.css index 281bca2c..8a49364f 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/index.css +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/index.css @@ -1,3 +1,6 @@ +/* 引入主题å˜é‡ */ +@import './variables.css'; + * { margin: 0; padding: 0; @@ -7,23 +10,57 @@ html, body { height: 100%; font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif; + background-color: var(--bg-page); } #app { height: 100%; } -/* æ»šåŠ¨æ¡æ ·å¼ */ +/* æ»šåŠ¨æ¡æ ·å¼ - æµ…è“主题 */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-thumb { - background-color: #dcdfe6; + background-color: var(--primary-light); border-radius: 3px; } -::-webkit-scrollbar-track { - background-color: #f5f7fa; +::-webkit-scrollbar-thumb:hover { + background-color: var(--primary-color); +} + +::-webkit-scrollbar-track { + background-color: var(--bg-light); +} + +/* å…¨å±€é“¾æŽ¥æ ·å¼ */ +a { + color: var(--primary-color); + text-decoration: none; +} + +a:hover { + color: var(--primary-dark); +} + +/* å¡ç‰‡é€šç”¨æ ·å¼ */ +.el-card { + border-radius: var(--border-radius-large); + border: 1px solid var(--border-lighter); + box-shadow: var(--box-shadow-light); +} + +/* è¡¨æ ¼å¤´éƒ¨æ ·å¼ */ +.el-table th.el-table__cell { + background-color: var(--bg-light) !important; + color: var(--text-primary); +} + +/* æŒ‰é’®æ‚¬åœæ•ˆæžœå¢žå¼º */ +.el-button--primary:hover { + background-color: var(--primary-dark); + border-color: var(--primary-dark); } diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/variables.css b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/variables.css new file mode 100644 index 00000000..c3eb1e37 --- /dev/null +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/styles/variables.css @@ -0,0 +1,116 @@ +/** + * HoneyBox 管ç†åŽå° - 主题å˜é‡æ–‡ä»¶ + * æµ…è“色主题 (Light Blue Theme) + * + * 使用方å¼: var(--å˜é‡å) + * 切æ¢ä¸»é¢˜: 修改 :root 下的å˜é‡å€¼å³å¯ + */ + +:root { + /* ==================== å“牌色 ==================== */ + --primary-color: #4A90D9; /* 主色调 - å¤©ç©ºè“ */ + --primary-light: #74B9FF; /* 主色浅色 */ + --primary-dark: #2B7DE9; /* 主色深色 */ + --primary-bg: #E8F4FD; /* 主色背景 */ + + /* ==================== 功能色 ==================== */ + --success-color: #67C23A; /* æˆåŠŸè‰² */ + --warning-color: #E6A23C; /* 警告色 */ + --danger-color: #F56C6C; /* å±é™©è‰² */ + --info-color: #909399; /* ä¿¡æ¯è‰² */ + + /* ==================== 文字色 ==================== */ + --text-primary: #303133; /* ä¸»è¦æ–‡å­— */ + --text-regular: #606266; /* 常规文字 */ + --text-secondary: #909399; /* æ¬¡è¦æ–‡å­— */ + --text-placeholder: #C0C4CC; /* å ä½æ–‡å­— */ + --text-white: #FFFFFF; /* 白色文字 */ + + /* ==================== 边框色 ==================== */ + --border-base: #DCDFE6; /* 基础边框 */ + --border-light: #E4E7ED; /* 浅色边框 */ + --border-lighter: #EBEEF5; /* 更浅边框 */ + --border-extra-light: #F2F6FC; /* æžæµ…边框 */ + + /* ==================== 背景色 ==================== */ + --bg-white: #FFFFFF; /* 白色背景 */ + --bg-page: #F5F9FC; /* 页é¢èƒŒæ™¯ - æžæµ…è“ */ + --bg-light: #F0F7FF; /* 浅色背景 */ + --bg-hover: #E8F4FD; /* 悬åœèƒŒæ™¯ */ + + /* ==================== ä¾§è¾¹æ  ==================== */ + --sidebar-bg: #F0F7FF; /* ä¾§è¾¹æ èƒŒæ™¯ - æµ…è“白 */ + --sidebar-logo-bg: #4A90D9; /* Logo区背景 - 主è“色 */ + --sidebar-text: #606266; /* ä¾§è¾¹æ æ–‡å­— */ + --sidebar-text-active: #4A90D9; /* ä¾§è¾¹æ æ¿€æ´»æ–‡å­— */ + --sidebar-item-hover: #E8F4FD; /* èœå•项悬åœèƒŒæ™¯ */ + --sidebar-item-active: #E8F4FD; /* èœå•项激活背景 */ + --sidebar-submenu-bg: #E8F4FD; /* å­èœå•背景 */ + --sidebar-width: 200px; /* ä¾§è¾¹æ å®½åº¦ */ + --sidebar-width-collapsed: 64px; /* 折å åŽå®½åº¦ */ + + /* ==================== é¡¶éƒ¨æ  ==================== */ + --header-bg: #FFFFFF; /* 顶部æ èƒŒæ™¯ */ + --header-height: 50px; /* 顶部æ é«˜åº¦ */ + --header-shadow: 0 1px 4px rgba(74, 144, 217, 0.1); /* 顶部æ é˜´å½± */ + + /* ==================== 登录页 ==================== */ + --login-bg-start: #74B9FF; /* 登录页æ¸å˜èµ·å§‹è‰² */ + --login-bg-end: #4A90D9; /* 登录页æ¸å˜ç»“æŸè‰² */ + --login-box-shadow: 0 4px 20px rgba(74, 144, 217, 0.15); /* 登录框阴影 */ + + /* ==================== 圆角 ==================== */ + --border-radius-small: 4px; + --border-radius-base: 6px; + --border-radius-large: 8px; + --border-radius-round: 20px; + + /* ==================== 阴影 ==================== */ + --box-shadow-light: 0 2px 12px rgba(0, 0, 0, 0.05); + --box-shadow-base: 0 2px 12px rgba(74, 144, 217, 0.1); + --box-shadow-dark: 0 4px 20px rgba(74, 144, 217, 0.15); + + /* ==================== 过渡动画 ==================== */ + --transition-duration: 0.3s; + --transition-timing: ease; +} + +/* ==================== Element Plus 主题覆盖 ==================== */ +:root { + /* 覆盖 Element Plus 主色 */ + --el-color-primary: var(--primary-color); + --el-color-primary-light-3: #7AB4E8; + --el-color-primary-light-5: #A4CDF0; + --el-color-primary-light-7: #CEE6F8; + --el-color-primary-light-8: #E3F0FB; + --el-color-primary-light-9: #F0F7FF; + --el-color-primary-dark-2: #3B73AE; + + /* 覆盖功能色 */ + --el-color-success: var(--success-color); + --el-color-warning: var(--warning-color); + --el-color-danger: var(--danger-color); + --el-color-info: var(--info-color); + + /* 覆盖文字色 */ + --el-text-color-primary: var(--text-primary); + --el-text-color-regular: var(--text-regular); + --el-text-color-secondary: var(--text-secondary); + --el-text-color-placeholder: var(--text-placeholder); + + /* 覆盖边框色 */ + --el-border-color: var(--border-base); + --el-border-color-light: var(--border-light); + --el-border-color-lighter: var(--border-lighter); + --el-border-color-extra-light: var(--border-extra-light); + + /* 覆盖背景色 */ + --el-bg-color: var(--bg-white); + --el-bg-color-page: var(--bg-page); + --el-bg-color-overlay: var(--bg-white); + + /* 覆盖圆角 */ + --el-border-radius-base: var(--border-radius-base); + --el-border-radius-small: var(--border-radius-small); + --el-border-radius-round: var(--border-radius-round); +} diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/dashboard/index.vue b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/dashboard/index.vue index 0f74ce33..97846bd2 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/dashboard/index.vue +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/dashboard/index.vue @@ -3,7 +3,7 @@ -
+
@@ -14,7 +14,7 @@ -
+
@@ -25,7 +25,7 @@ -
+
@@ -36,7 +36,7 @@ -
+
@@ -137,6 +137,12 @@ onMounted(() => { display: flex; align-items: center; padding: 20px; + transition: all var(--transition-duration) var(--transition-timing); +} + +.stat-card:hover { + transform: translateY(-4px); + box-shadow: var(--box-shadow-dark); } .stat-card :deep(.el-card__body) { @@ -148,14 +154,30 @@ onMounted(() => { .stat-icon { width: 64px; height: 64px; - border-radius: 8px; + border-radius: var(--border-radius-large); display: flex; align-items: center; justify-content: center; - color: #fff; + color: var(--text-white); margin-right: 16px; } +.stat-icon-primary { + background: linear-gradient(135deg, var(--primary-light) 0%, var(--primary-color) 100%); +} + +.stat-icon-success { + background: linear-gradient(135deg, #95d475 0%, var(--success-color) 100%); +} + +.stat-icon-warning { + background: linear-gradient(135deg, #f0c78a 0%, var(--warning-color) 100%); +} + +.stat-icon-danger { + background: linear-gradient(135deg, #f89898 0%, var(--danger-color) 100%); +} + .stat-content { flex: 1; } @@ -163,12 +185,12 @@ onMounted(() => { .stat-value { font-size: 28px; font-weight: bold; - color: #303133; + color: var(--text-primary); } .stat-label { font-size: 14px; - color: #909399; + color: var(--text-secondary); margin-top: 4px; } @@ -178,12 +200,12 @@ onMounted(() => { .welcome-content h2 { margin: 0 0 16px 0; - color: #303133; + color: var(--primary-color); } .welcome-content p { margin: 8px 0; - color: #606266; + color: var(--text-regular); } .quick-actions { @@ -191,4 +213,11 @@ onMounted(() => { gap: 12px; flex-wrap: wrap; } + +:deep(.el-card__header) { + background-color: var(--bg-light); + border-bottom: 1px solid var(--border-lighter); + font-weight: 500; + color: var(--text-primary); +} diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/login/index.vue b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/login/index.vue index 6d6ad9b0..3849c3a3 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/login/index.vue +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/login/index.vue @@ -102,15 +102,42 @@ const handleLogin = async () => { display: flex; justify-content: center; align-items: center; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient(135deg, var(--login-bg-start) 0%, var(--login-bg-end) 100%); + position: relative; + overflow: hidden; +} + +/* 装饰性背景圆 */ +.login-container::before { + content: ''; + position: absolute; + width: 600px; + height: 600px; + background: rgba(255, 255, 255, 0.1); + border-radius: 50%; + top: -200px; + right: -200px; +} + +.login-container::after { + content: ''; + position: absolute; + width: 400px; + height: 400px; + background: rgba(255, 255, 255, 0.08); + border-radius: 50%; + bottom: -150px; + left: -150px; } .login-box { width: 400px; padding: 40px; - background: #fff; - border-radius: 8px; - box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); + background: var(--bg-white); + border-radius: var(--border-radius-large); + box-shadow: var(--login-box-shadow); + position: relative; + z-index: 1; } .login-header { @@ -120,8 +147,12 @@ const handleLogin = async () => { .login-header h1 { font-size: 24px; - color: #303133; + color: var(--text-primary); margin: 0; + background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; } .login-form { @@ -130,5 +161,25 @@ const handleLogin = async () => { .login-btn { width: 100%; + background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%); + border: none; + transition: all var(--transition-duration) var(--transition-timing); +} + +.login-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(74, 144, 217, 0.4); +} + +:deep(.el-input__wrapper) { + border-radius: var(--border-radius-base); +} + +:deep(.el-input__wrapper:hover) { + box-shadow: 0 0 0 1px var(--primary-light) inset; +} + +:deep(.el-input__wrapper.is-focus) { + box-shadow: 0 0 0 1px var(--primary-color) inset; }