فهرست منبع

feat(home): 添加首页信息展示功能- 新增 HomeController 提供首页信息接口
- 实现 HomeService 获取产品、新闻、职位、荣誉数量统计
- 创建 HomeInfoVo 数据传输对象封装首页数据
- 添加全局异常处理器对 BusinessException 的处理支持

nahida 7 ماه پیش
والد
کامیت
8b6d6caf76

+ 23 - 0
zksy-admin/src/main/java/com/zksy/web/controller/base/HomeController.java

@@ -0,0 +1,23 @@
+package com.zksy.web.controller.base;
+
+import com.zksy.base.service.HomeService;
+import com.zksy.common.core.domain.AjaxResult;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/home")
+public class HomeController {
+
+    @Autowired
+    private HomeService homeService;
+
+    @GetMapping("/getHomeInfo")
+    @ApiOperation("获取首页信息")
+    public AjaxResult getHomeInfo() {
+        return AjaxResult.success(homeService.getHomeInfo());
+    }
+}

+ 206 - 0
zksy-admin/src/main/resources/static/index.html

@@ -0,0 +1,206 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>不要攻击我</title>
+    <style>
+        * {
+            margin: 0;
+            padding: 0;
+            box-sizing: border-box;
+        }
+
+        body {
+            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+            line-height: 1.8;
+            color: #555;
+            background-color: #faf7f7;
+            padding: 0;
+            margin: 0;
+        }
+
+        header {
+            background-color: #fff3f3;
+            color: #d35454;
+            text-align: center;
+            padding: 2.5rem 1rem;
+            border-bottom: 1px solid #ffdddd;
+        }
+
+        h1 {
+            font-size: 2.2rem;
+            margin-bottom: 1rem;
+            font-weight: 500;
+            letter-spacing: 0.5px;
+        }
+
+        header p {
+            font-size: 1.1rem;
+            max-width: 700px;
+            margin: 0 auto;
+            color: #777;
+        }
+
+        .container {
+            max-width: 900px;
+            margin: 0 auto;
+            padding: 2rem 1rem;
+        }
+
+        .content-card {
+            background-color: white;
+            border-radius: 12px;
+            box-shadow: 0 2px 8px rgba(0,0,0,0.05);
+            padding: 2rem;
+            margin-bottom: 1.5rem;
+            border: 1px solid #f0f0f0;
+        }
+
+        .content-card p {
+            margin-bottom: 1rem;
+            color: #666;
+        }
+
+        .beg-text {
+            color: #d35454;
+            font-weight: 500;
+            font-size: 1.05rem;
+        }
+
+        .detail {
+            font-size: 0.95rem;
+            color: #888;
+            margin-top: 0.5rem;
+            line-height: 1.6;
+        }
+
+        .icon-group {
+            display: flex;
+            justify-content: center;
+            margin: 1.5rem 0;
+            gap: 2rem;
+        }
+
+        .small-icon {
+            width: 50px;
+            height: 50px;
+            color: #d3545433;
+        }
+
+        .beg-btn {
+            display: block;
+            width: 200px;
+            margin: 2rem auto 0;
+            background-color: #fff3f3;
+            color: #d35454;
+            padding: 0.8rem 1rem;
+            border-radius: 25px;
+            text-align: center;
+            text-decoration: none;
+            font-size: 1rem;
+            border: 1px solid #ffdddd;
+            transition: all 0.3s ease;
+            cursor: pointer;
+        }
+
+        .beg-btn:hover {
+            background-color: #ffebeb;
+            transform: scale(1.03);
+        }
+
+        footer {
+            background-color: #fff3f3;
+            color: #999;
+            text-align: center;
+            padding: 1.5rem 1rem;
+            margin-top: 2rem;
+            font-size: 0.9rem;
+            border-top: 1px solid #ffdddd;
+        }
+
+        footer p {
+            margin: 0.3rem 0;
+        }
+
+        @media (max-width: 768px) {
+            h1 {
+                font-size: 1.8rem;
+            }
+
+            .content-card {
+                padding: 1.5rem;
+            }
+
+            .small-icon {
+                width: 40px;
+                height: 40px;
+            }
+        }
+    </style>
+</head>
+<body>
+<header>
+    <h1>不要攻击我</h1>
+    <p>我只是一个很普通的小网站,真的经不起任何折腾...</p>
+</header>
+
+<div class="container">
+    <div class="content-card">
+        <p>求求您了,别攻击我好不好?</p>
+        <p class="beg-text">我不是什么重要的网站,就是个人随便做的小玩意儿,里面也没有值钱的东西...</p>
+        <p class="detail">要是被攻击了,我可能连修都修不好——我对技术也不太懂,当初做这个网站已经花了好长时间,要是坏了,真的不知道该怎么办了...</p>
+    </div>
+
+    <div class="content-card">
+        <p>我知道我可能做得不好,有很多漏洞...</p>
+        <p class="beg-text">但您要是发现问题,能不能别用攻击的方式?哪怕不管我也好,别让我直接用不了行不行?</p>
+        <p class="detail">之前听说有的网站被攻击后,所有数据都没了,我一想到这个就特别害怕...我这个小站虽然没什么用,但也是我一点点搭起来的,真的不想它就这么没了...</p>
+
+        <div class="icon-group">
+            <svg class="small-icon" viewBox="0 0 24 24" fill="currentColor">
+                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
+                <path d="M12 6v6l5 3-5 3V6z"/>
+            </svg>
+            <svg class="small-icon" viewBox="0 0 24 24" fill="currentColor">
+                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
+                <path d="M12 7c-.55 0-1 .45-1 1v5c0 .55.45 1 1 1s1-.45 1-1V8c0-.55-.45-1-1-1z"/>
+            </svg>
+        </div>
+    </div>
+
+    <div class="content-card">
+        <p class="beg-text">真的拜托您了,手下留情...</p>
+        <p>我保证不会给任何人添麻烦,就安安静静地待在这里就好。要是您能高抬贵手,不攻击我,我真的特别特别感谢您...</p>
+
+        <button class="beg-btn">求求您别攻击我</button>
+    </div>
+</div>
+
+<footer>
+    <p>一个很弱小的小网站</p>
+    <p>只希望能安安稳稳地存在着</p>
+</footer>
+
+<script>
+    document.querySelector('.beg-btn').addEventListener('click', function() {
+        alert('谢谢您...谢谢您愿意手下留情...');
+    });
+
+    document.addEventListener('DOMContentLoaded', function() {
+        const cards = document.querySelectorAll('.content-card');
+        cards.forEach((card, index) => {
+            card.style.opacity = '0';
+            card.style.transform = 'translateY(15px)';
+            card.style.transition = `opacity 0.6s ease ${index * 0.2}s, transform 0.6s ease ${index * 0.2}s`;
+
+            // 延迟触发淡入
+            setTimeout(() => {
+                card.style.opacity = '1';
+                card.style.transform = 'translateY(0)';
+            }, 100);
+        });
+    });
+</script>
+</body>
+</html>

+ 9 - 0
zksy-framework/src/main/java/com/zksy/framework/web/exception/GlobalExceptionHandler.java

@@ -1,6 +1,8 @@
 package com.zksy.framework.web.exception;
 
 import javax.servlet.http.HttpServletRequest;
+
+import com.zksy.common.exception.BusinessException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.access.AccessDeniedException;
@@ -63,6 +65,13 @@ public class GlobalExceptionHandler
         return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
     }
 
+    @ExceptionHandler(BusinessException.class)
+    public Object handleBusinessException(BusinessException e) {
+        log.error("业务异常 -> {}", e.getMessage());
+        log.debug("", e);
+        return new AjaxResult(e.getCode(),e.getMessage(),e.getData());
+    }
+
     /**
      * 请求路径中缺少必需的路径变量
      */

+ 15 - 0
zksy-system/src/main/java/com/zksy/base/domain/vo/HomeInfoVo.java

@@ -0,0 +1,15 @@
+package com.zksy.base.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class HomeInfoVo {
+    private Integer productCount;
+    private Integer newsCount;
+    private Integer jobCount;
+    private Integer honerCount;
+}

+ 7 - 0
zksy-system/src/main/java/com/zksy/base/service/HomeService.java

@@ -0,0 +1,7 @@
+package com.zksy.base.service;
+
+import com.zksy.base.domain.vo.HomeInfoVo;
+
+public interface HomeService {
+    HomeInfoVo getHomeInfo();
+}

+ 27 - 0
zksy-system/src/main/java/com/zksy/base/service/impl/HomeServiceImpl.java

@@ -0,0 +1,27 @@
+package com.zksy.base.service.impl;
+
+import com.zksy.base.domain.vo.HomeInfoVo;
+import com.zksy.base.service.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class HomeServiceImpl implements HomeService {
+    @Autowired
+    private NewsUpdatesService newsUpdatesService;
+    @Autowired
+    private ProductCenterService productCenterService;
+    @Autowired
+    private SmartEmploymentService smartEmploymentService;
+    @Autowired
+    private QualificationCertificateService qualificationCertificateService;
+    @Override
+    public HomeInfoVo getHomeInfo() {
+        HomeInfoVo homeInfoVo = new HomeInfoVo();
+        homeInfoVo.setProductCount((int) productCenterService.count());
+        homeInfoVo.setNewsCount((int) newsUpdatesService.count());
+        homeInfoVo.setJobCount((int) smartEmploymentService.count());
+        homeInfoVo.setHonerCount((int) qualificationCertificateService.count());
+        return homeInfoVo;
+    }
+}