<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      培訓管理子系統開發3

      整個項目預期的任務量 (任務量 = 所有工作的預期時間10天)和 目前已經花的時間 (所有記錄的 ‘已經花費的時間’3天),還剩余的時間(所有工作的 ‘剩余時間’7天)

      實現了員工管理功能,查看員工選課情況

      刪除功能如果員工存在選課記錄無法刪除

      // 員工管理
          @GetMapping("/employees")
          public String employeeManage(Model model) {
              // 獲取員工列表
              List<User> employees = adminService.findAllEmployees();
      
              // 獲取員工課程映射表
              Map<Integer, List<Course>> coursesMap = adminService.getEmployeeCoursesMap();
      
              model.addAttribute("employees", employees);
              model.addAttribute("coursesMap", coursesMap);
              return "admin/employee";
          }
      
          // 員工刪除
          @PostMapping("/employees/delete/{id}")
          public String deleteEmployee(@PathVariable Integer id,
                                       HttpSession session,
                                       RedirectAttributes ra) {
              if (!checkAdmin(session)) return "redirect:/login";
      
              try {
                  adminService.deleteEmployee(id);
                  ra.addFlashAttribute("success", "員工刪除成功");
              } catch (AdminService.ServiceException e) {
                  ra.addFlashAttribute("error", e.getMessage());
              } catch (Exception e) {
                  ra.addFlashAttribute("error", "系統錯誤:" + e.getMessage());
              }
              return "redirect:/admin/employees";
          }
      package com.example.training.repository;
      
      import com.example.training.entity.EmployeeCourse;
      import org.springframework.data.jpa.repository.JpaRepository;
      import org.springframework.data.jpa.repository.Query;
      import org.springframework.data.repository.query.Param;
      import java.util.List;
      import java.util.Optional;
      
      public interface EmployeeCourseRepository extends JpaRepository<EmployeeCourse, Integer> {
      
          @Query("SELECT ec FROM EmployeeCourse ec " +
                  "WHERE ec.employee.id = :employeeId " +
                  "AND ec.active = true")
          List<EmployeeCourse> findActiveCoursesByEmployee(@Param("employeeId") Integer employeeId);
      
          @Query("SELECT COUNT(ec) > 0 FROM EmployeeCourse ec " +
                  "WHERE ec.employee.id = :employeeId " +
                  "AND ec.course.id = :courseId " +
                  "AND ec.active = true")
          boolean existsActiveSelection(@Param("employeeId") Integer employeeId,
                                        @Param("courseId") Integer courseId);
      
          @Query("UPDATE EmployeeCourse ec SET ec.active = false " +
                  "WHERE ec.employee.id = :employeeId " +
                  "AND ec.course.id = :courseId")
          void cancelCourseSelection(@Param("employeeId") Integer employeeId,
                                     @Param("courseId") Integer courseId);
      
      
          @Query("SELECT COUNT(ec) > 0 FROM EmployeeCourse ec WHERE ec.course.id = :courseId")
          boolean existsByCourseId(@Param("courseId") Integer courseId);
      
          @Query("SELECT COUNT(ec) > 0 FROM EmployeeCourse ec WHERE ec.employee.id = :employeeId")
          boolean existsByEmployeeId(@Param("employeeId") Integer employeeId);
      
          @Query("SELECT ec FROM EmployeeCourse ec WHERE ec.employee.id = :employeeId AND ec.course.id = :courseId")
          Optional<EmployeeCourse> findByEmployeeIdAndCourseId(
                  @Param("employeeId") Integer employeeId,
                  @Param("courseId") Integer courseId);
          @Query("SELECT ec FROM EmployeeCourse ec JOIN FETCH ec.course WHERE ec.employee.id IN :employeeIds")
          List<EmployeeCourse> findWithCoursesByEmployeeIds(@Param("employeeIds") List<Integer> employeeIds);
      
      }
      <!DOCTYPE html>
      <html xmlns:th="http://www.thymeleaf.org">
      <head>
          <title>員工管理</title>
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <style>
              /* 增強基礎樣式 */
              body {
                  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
                  background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
                  margin: 0;
                  min-height: 100vh;
                  padding: 2rem;
              }
      
              .container {
                  background: rgba(255, 255, 255, 0.98);
                  border-radius: 16px;
                  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
                  padding: 2.5rem;
                  max-width: 1000px;
                  margin: 0 auto;
                  backdrop-filter: blur(8px);
              }
      
              h2 {
                  color: #1e3c72;
                  margin: 0 0 2rem;
                  padding-bottom: 1rem;
                  border-bottom: 3px solid #1e3c72;
                  font-size: 2rem;
                  letter-spacing: -0.5px;
              }
      
              /* 提示信息樣式 */
              .alert {
                  padding: 1rem 1.5rem;
                  border-radius: 8px;
                  margin: 1.5rem 0;
                  font-weight: 500;
              }
      
              .alert.success {
                  background: #e8f6ef;
                  color: #2e7d32;
                  border: 1px solid #a5d6a7;
              }
      
              .alert.error {
                  background: #ffebee;
                  color: #c62828;
                  border: 1px solid #ffcdd2;
              }
      
              /* 返回鏈接優化 */
              .back-link {
                  display: inline-flex;
                  align-items: center;
                  gap: 0.5rem;
                  color: #2a5298;
                  padding: 0.8rem 1.2rem;
                  border-radius: 6px;
                  background: rgba(42,82,152,0.1);
                  transition: all 0.2s ease;
                  margin-bottom: 2rem;
              }
      
              .back-link:hover {
                  background: rgba(42,82,152,0.2);
                  transform: translateX(-3px);
                  text-decoration: none;
              }
      
              /* 表格增強 */
              table {
                  border-radius: 12px;
                  overflow: hidden;
                  box-shadow: 0 2px 6px rgba(0,0,0,0.05);
                  background: white;
                  margin-top: 2rem;
              }
      
              th {
                  background: linear-gradient(135deg, #1e3c72, #2a5298);
                  color: white;
                  font-weight: 600;
                  padding: 1rem 1.5rem;
              }
      
              td {
                  padding: 1rem 1.5rem;
                  border-bottom: 1px solid #f0f4f8;
              }
      
              tr:hover {
                  background: #f8fafc !important;
              }
      
              /* 刪除按鈕樣式 */
              .btn-delete {
                  background: #c62828 !important;
                  color: white !important;
                  padding: 0.5rem 1.2rem;
                  border-radius: 6px;
                  border: none;
                  cursor: pointer;
                  transition: all 0.2s ease;
                  font-weight: 500;
              }
      
              .btn-delete:hover {
                  background: #b71c1c !important;
                  transform: translateY(-1px);
                  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
              }
      
              /* 響應式優化 */
              @media (max-width: 768px) {
                  .container {
                      padding: 1.5rem;
                  }
      
                  table {
                      display: block;
                      overflow-x: auto;
                  }
      
                  th, td {
                      min-width: 120px;
                  }
              }
      
              .alert-container {
                  position: fixed;
                  top: 80px;  /* 在導航欄下方 */
                  right: 20px;
                  z-index: 1000;
              }
      
          </style>
      </head>
      <body>
      <div class="container">
          <!-- 提示信息 -->
          <div class="alert-container">
              <div th:if="${success}" class="alert success" th:text="${success}"></div>
              <div th:if="${error}" class="alert error" th:text="${error}"></div>
          </div>
      
          <h2>員工管理系統</h2>
      
          <h3>員工列表</h3>
          <table border="1">
              <thead>
              <tr>
                  <th>用戶名</th>
                  <th>已選課程</th>
                  <th style="width:120px;">操作</th>
              </tr>
              </thead>
              <tbody>
              <tr th:each="emp : ${employees}">
                  <td th:text="${emp.name}"></td>
                  <!-- 已選課程 -->
                  <td>
                      <div th:if="${coursesMap.containsKey(emp.id)}">
                          <div th:each="course : ${coursesMap.get(emp.id)}">
                              <span th:text="${course.name}"></span>
                              <small>(授課教師:<span th:text="${course.teacher}"></span>)</small>
                          </div>
                      </div>
                      <span th:unless="${coursesMap.containsKey(emp.id)}">未選擇任何課程</span>
                  </td>
      
                  <td>
                      <form th:action="@{/admin/employees/delete/{id}(id=${emp.id})}"
                            method="post"
                            onsubmit="return confirm('確定刪除該員工嗎?');">
                          <button type="submit" class="btn-delete">刪除</button>
                      </form>
                  </td>
              </tr>
              </tbody>
          </table>
      </div>
      </body>
      </html>
      
      posted @ 2025-04-17 22:53  霸王雞  閱讀(15)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 九九热免费精品视频在线| 国产国产午夜福利视频| 色噜噜狠狠一区二区三区果冻| 激情六月丁香婷婷四房播 | 欧美性猛交xxxx乱大交丰满| 欧美奶涨边摸边做爰视频| 精品国产成人午夜福利| 色护士极品影院| 玉田县| 中国china露脸自拍性hd| 九九热在线精品免费视频| 日韩一区二区三在线观看| 欧美18videosex性欧美tube1080| 在线日韩日本国产亚洲| 精品国产综合一区二区三区| 亚洲中文字幕亚洲中文精| 视频一区视频二区制服丝袜 | 亚洲精品动漫免费二区| 国产欧美日韩视频一区二区三区| 久久精品国产福利一区二区| aa性欧美老妇人牲交免费| 少妇人妻真实偷人精品| 免费a级毛片无码av| 日本熟妇浓毛hdsex| 亚洲肥熟女一区二区三区| 一本一本久久A久久精品综合不卡| 亚洲黄色成人网在线观看| 亚洲成av人片无码迅雷下载| 欧美肥老太交视频免费| 乌兰浩特市| 蜜臀av午夜精品福利| 成人无号精品一区二区三区| 欧美激欧美啪啪片| 久久午夜无码鲁丝片直播午夜精品| 镇远县| 成人网站免费观看永久视频下载 | 历史| 精品精品亚洲高清a毛片| 久久精品无码鲁网中文电影| 国产一级av在线播放| 中文字幕自拍偷拍福利视频|