GTong 8 hónapja
szülő
commit
a4bd70178f

+ 7 - 0
internal/api/license_api.go

@@ -78,3 +78,10 @@ type UpdateLicenseInfoRequest struct {
 	Version           string `json:"Version" `
 	NodeCount         int64  `json:"NodeCount"`
 }
+
+type ConditionalSearchRequest struct {
+	LicenseFlag string `json:"license_flag,omitempty"`
+	StartingDate  string `json:"starting_date,omitempty"`
+	EndDate       string `json:"end_date,omitempty"`
+	AnySearch     string `json:"any_search,omitempty"`
+}

+ 30 - 0
internal/controllers/OALicenseInfo_controllers.go

@@ -709,3 +709,33 @@ func SearchLicInfoToDb(c *gin.Context) {
 	}
 
 }
+
+func ConditionalSearchController(c *gin.Context) {
+	// 解析 JSON 请求体
+	var request api.ConditionalSearchRequest
+	if err := c.ShouldBindJSON(&request); err != nil {
+		c.JSON(400, gin.H{
+			"error": err.Error(),
+		})
+		return
+	}
+	if request.AnySearch == "" && request.EndDate == "" && request.StartingDate == "" && request.LicenseFlag == "" {
+		c.JSON(400, gin.H{
+			"error": "请求参数不能为空",
+		})
+		return
+	}
+
+	licInfos, err := services.GetConditionalSearchService(request)
+	if err != nil {
+		c.JSON(400, gin.H{
+			"error": errors.Errorf("查询失败: %s", err.Error()),
+		})
+		return
+	}
+
+	c.JSON(http.StatusOK, gin.H{
+		"success": true,
+		"data":    licInfos,
+	})
+}

+ 95 - 0
internal/models/license_oa_models.go

@@ -4,7 +4,9 @@ import (
 	"database/sql"
 	"fmt"
 	"log"
+	"strings"
 	"time"
+	"xugu_license/internal/api"
 	"xugu_license/internal/global"
 )
 
@@ -928,3 +930,96 @@ func CheckOaLicRequest(oaRequestID string, userUNIQUEID string) (bool, error) {
 
 	return true, nil
 }
+
+// ------------------按搜索条件查询license表--------------------
+// 假设你有一个结构体保存传入的参数
+
+func buildSQL(params api.ConditionalSearchRequest) (string, []interface{}) {
+	// 基础SQL查询
+	baseSQL := `SELECT 
+		la.ID, la.Unique_ID, la.OA_ID, la.OA_REQUESTID, la.OA_REQUESTNAME, la.OA_REQUESTNAMENEW,
+		la.OA_REQUESTNAMEHTMLNEW, la.OA_GLXMID ,la.OA_GLXMNAME ,la.OA_SQSJ, la.OA_SALESPERSONNAME, la.OA_XSJSYX,
+		la.OA_OPERATIONSPERSONNAME, la.OA_JFJSYX, la.OA_SYDW, la.OA_XMXXMS, la.OA_JDS,
+		la.OA_NODECOUNT, la.OA_PRODUCTCODE, la.OA_PRODUCTNAME, la.OA_PRODUCTVERSION,
+		la.OA_CPU, la.OA_OPERATINGSYSTEM, la.OA_MAINMAC, la.OA_SECONDMAC, la.OA_CREATIONDATE,
+		la.OA_CREATIONTIME, la.OA_LASTOPERATEDATE, la.OA_LASTOPERATETIME, la.capture_Time,
+		la.del_Time, la.LAST_OPERATE_TIME,
+		li.ID AS License_ID, li.OA_ID, li.License_UniqueID, li.License_Flage, li.lic1, li.lic2, li.Creator_generate
+	FROM 
+		target_OA_license la
+	INNER JOIN 
+		License_generate_Info li
+		ON 
+		la.Unique_ID = li.License_UniqueID
+	WHERE 1=1`
+
+	// 动态条件部分
+	var conditions []string
+	var args []interface{}
+
+	// 根据 LicenseFlag 生成条件
+	if params.LicenseFlag != "" {
+		conditions = append(conditions, "li.License_Flage = ?")
+		args = append(args, params.LicenseFlag)
+	}
+
+	// 根据 StartingDate 生成条件,将字符串转换为日期
+	if params.StartingDate != "" {
+		conditions = append(conditions, "TO_DATE(la.OA_CREATIONDATE, 'YYYY-MM-DD') >= ?")
+		args = append(args, params.StartingDate)
+	}
+
+	// 根据 EndDate 生成条件,将字符串转换为日期
+	if params.EndDate != "" {
+		conditions = append(conditions, "TO_DATE(la.OA_CREATIONDATE, 'YYYY-MM-DD') <= ?")
+		args = append(args, params.EndDate)
+	}
+
+	// 如果有条件,将条件加入SQL语句中
+	if len(conditions) > 0 {
+		baseSQL += " AND " + strings.Join(conditions, " AND ")
+	}
+
+	return baseSQL, args
+}
+func GetConditionalSearch(params api.ConditionalSearchRequest) (*[]OALicenseInfo, error) {
+
+	// 构建SQL语句和参数
+	query, args := buildSQL(params)
+	// 输出SQL语句和参数
+	fmt.Println("Query:", query)
+	fmt.Println("Args:", args)
+	rows, err := global.XuguDB.Query(query, args...)
+	if err != nil {
+		global.Logger.Errorln("getLicInfoByOAUniqueID 数据查询失败: ", err.Error())
+		return nil, fmt.Errorf("getLicInfoByOAUniqueID 数据查询失败: %v", err)
+	}
+	defer rows.Close()
+	var rest []OALicenseInfo
+	for rows.Next() {
+		var info OALicenseInfo
+		err = rows.Scan(
+			&info.LicInfo.ID, &info.LicInfo.UniqueID, &info.LicInfo.OAId, &info.LicInfo.OARequestID,
+			&info.LicInfo.OARequestName, &info.LicInfo.OARequestNameNew, &info.LicInfo.OARequestNameHTMLNew,
+			&info.LicInfo.OAGLXMID, &info.LicInfo.OAGLXMName,
+			&info.LicInfo.OASQSJ, &info.LicInfo.OASalespersonName, &info.LicInfo.OAXSJSYX,
+			&info.LicInfo.OAOperationsPersonName, &info.LicInfo.OAJFJSYX, &info.LicInfo.OASYDW,
+			&info.LicInfo.OAXMXXMS, &info.LicInfo.OAJDS, &info.LicInfo.OANodeCount,
+			&info.LicInfo.OAProductCode, &info.LicInfo.OAProductName, &info.LicInfo.OAProductVersion,
+			&info.LicInfo.OACPU, &info.LicInfo.OAOperatingSystem, &info.LicInfo.OAMainMAC,
+			&info.LicInfo.OASecondMAC, &info.LicInfo.OACreationDate, &info.LicInfo.OACreationTime,
+			&info.LicInfo.OALastOperateDate, &info.LicInfo.OALastOperateTime, &info.LicInfo.CaptureTime,
+			&info.LicInfo.DelTime, &info.LicInfo.LastOperateTime,
+			&info.GenrateInfo.ID, &info.GenrateInfo.OAId, &info.GenrateInfo.LicenseUniqueID, &info.GenrateInfo.LicenseFlage,
+			&info.GenrateInfo.Lic1, &info.GenrateInfo.Lic2, &info.GenrateInfo.CreatorGenerate,
+		)
+		if err != nil {
+			log.Fatal(err)
+		}
+		rest = append(rest, info)
+	
+		fmt.Println("info", info)
+	}
+
+	return &rest, nil
+}

+ 3 - 2
internal/router.go

@@ -38,7 +38,7 @@ func SetupRouter() *gin.Engine {
 
 	// 中间件配置
 	//configureMiddleware(r)
-
+	middlewares.CORSMiddleware()
 	// 静态文件服务配置
 	configureStaticFileServing(r)
 
@@ -92,7 +92,8 @@ func SetupRouter() *gin.Engine {
 		protected.GET("/GetCaptureLicenseOnce", middlewares.PermissionMiddleware(middlewares.CaptureLicenseOnceToDb), controllers.CaptureLicenseOnceToDb)
 		//搜索license
 		protected.GET("/GetSearchLicInfoToDb", middlewares.PermissionMiddleware(middlewares.ReadLicense), controllers.SearchLicInfoToDb)
-
+		protected.POST("/GetConditionalSearch", middlewares.PermissionMiddleware(middlewares.ReadLicense), controllers.ConditionalSearchController)
+		
 		//生成license new
 		protected.POST("/GenerateLicense", middlewares.PermissionMiddleware(middlewares.GenerateLicense), controllers.GenerateOALicenseStrController)
 

+ 8 - 0
internal/services/OALicenseInfo_services.go

@@ -249,3 +249,11 @@ func GetDistributeButtenCheckService(OARequestId string) (error, bool) {
 	}
 	return errors.Errorf("该申请单没有oa单号"), false
 }
+
+func GetConditionalSearchService(request api.ConditionalSearchRequest) (*[]models.OALicenseInfo, error) {
+	lic, err := models.GetConditionalSearch(request)
+	if err != nil {
+		return nil, err
+	}
+	return lic, nil
+}

+ 87 - 51
static/license_info/license_info.js

@@ -62,7 +62,7 @@ userManagementLink.addEventListener('click', function(event) {
             license_info_mainElement.innerHTML = data;
          // 动态引入 user.js 文件
          const script = document.createElement('script');
-         script.src = 'user.js';
+         script.src = '../user/user.js';
          document.body.appendChild(script);
             
         })
@@ -75,6 +75,28 @@ licenseInfoLink.addEventListener('click', function(event) {
 
     // 将瀑布流的 License 信息内容恢复到主内容区域
     const licenseInfoHtml = `
+        <!-- 包裹搜索框、下拉框、时间选择框和确定按钮的 div -->
+         <div class="search-container">
+            <!-- License 状态下拉框 -->
+            <select id="license-status-filter" aria-label="选择 License 状态">
+                <option value="">License 状态</option>
+                <option value="已生成">已生成</option>
+                <option value="未生成">未生成</option>
+                <option value="已失效">已失效</option>
+            </select>
+        
+            <!-- 开始时间选择框,类型改为 date -->
+            <input type="date" id="start-date" placeholder="开始时间" />
+        
+            <!-- 结束时间选择框,类型改为 date -->
+            <input type="date" id="end-date" placeholder="结束时间" />
+        
+            <!-- 搜索框 -->
+            <input type="text" id="search-bar" placeholder="搜索..." />
+        
+            <!-- 确定按钮 -->
+            <button id="submit-button">确定</button>
+        </div>
             <div class="license-info-container" id="license-info-restaurant-list">   </div>
     `; // 这是原来的 License 信息区域 HTML
 
@@ -107,7 +129,7 @@ roleManagementLink.addEventListener('click', function(event) {
             license_info_mainElement.innerHTML = data;
          // 动态引入 user.js 文件
          const script = document.createElement('script');
-         script.src = 'user.js';
+         script.src = '../role/role.js';
          document.body.appendChild(script);
             
         })
@@ -221,16 +243,16 @@ function renderLicenseCards(data, clearContainer = false) {
 
 
 // 检查是否滚动到底部并触发加载
-async function checkAndLoadMore(scrollHeight, scrollTop, clientHeight) {
-    if (isLoading || loadedItems >= total) return; // 如果正在加载或已加载完所有数据则退出
+// async function checkAndLoadMore(scrollHeight, scrollTop, clientHeight) {
+//     if (isLoading || loadedItems >= total) return; // 如果正在加载或已加载完所有数据则退出
 
-  //  console.log(`Scroll Info - scrollHeight: ${scrollHeight}, scrollTop: ${scrollTop}, clientHeight: ${clientHeight}`);
+//   //  console.log(`Scroll Info - scrollHeight: ${scrollHeight}, scrollTop: ${scrollTop}, clientHeight: ${clientHeight}`);
 
-    if (scrollTop + clientHeight >= scrollHeight - preLoadDistance) {
-        console.log(`触发加载更多数据:page=${page}, pageSize=${pageSize}`); // 每次触发时打印输出
-        await loadMoreData();
-    }
-}
+//     if (scrollTop + clientHeight >= scrollHeight - preLoadDistance) {
+//         console.log(`触发加载更多数据:page=${page}, pageSize=${pageSize}`); // 每次触发时打印输出
+//         await loadMoreData();
+//     }
+// }
 
 // 加载更多数据函数
 async function loadMoreData() {
@@ -277,7 +299,8 @@ async function loadMoreData() {
     isLoading = false; // 请求完成,允许下次请求
 
     // 检查内容高度,必要时继续加载
-    checkContentHeight();
+    //checkContentHeight();
+    checkAndLoadMore();
 }
 
 
@@ -334,7 +357,8 @@ async function checkAndLoadMore(scrollHeight, scrollTop, clientHeight) {
     //license_info_loadingIndicator.style.display = 'none'; // 初始化后隐藏加载提示
 
     // 检查内容高度
-    checkContentHeight();
+   // checkContentHeight();
+   checkAndLoadMore()
 })();
 //初始化监听滚动条
 initializeScrollListeners()
@@ -919,6 +943,7 @@ document.addEventListener('DOMContentLoaded', createLoadingModal);
 
 // 获取搜索框元素
 // 获取搜索框、状态下拉框、时间选择框和按钮元素
+// 获取搜索框、状态下拉框、时间选择框和按钮元素
 const searchBar = document.getElementById('search-bar');
 const statusFilter = document.getElementById('license-status-filter');
 const startDate = document.getElementById('start-date');
@@ -931,47 +956,58 @@ submitButton.addEventListener('click', filterContent);
 
 // 过滤功能实现
 function filterContent() {
-    const searchTerm = searchBar.value.toLowerCase();
-    const selectedStatus = statusFilter.value;
-    const selectedStartDate = startDate.value;  // 日期格式为 YYYY-MM-DD
-    const selectedEndDate = endDate.value;      // 日期格式为 YYYY-MM-DD
-
-    // 获取所有 License 卡片
-    const licenseCards = document.querySelectorAll('.license-info-card');
-
-    licenseCards.forEach(function(card) {
-        const cardText = card.textContent.toLowerCase();  // 获取卡片文本
-
-        // 获取许可证状态,确保许可证状态元素存在
-        const statusElement = card.querySelector('.license-status');
-        const cardStatus = statusElement ? statusElement.textContent.trim() : '';
-
-        // 获取日期,确保日期元素存在
-        const dateElement = card.querySelector('.card-text.date');
-        const cardDate = dateElement ? dateElement.textContent.trim() : '';
-
-        // 检查是否符合搜索条件
-        const matchesSearch = cardText.includes(searchTerm);
-        
-        // 检查许可证状态是否符合过滤条件
-        const matchesStatus = !selectedStatus || cardStatus === selectedStatus;
+    // 构建请求体参数
+    const requestData = {
+        license_flag: statusFilter.value || undefined,
+        starting_date: startDate.value || undefined,
+        end_date: endDate.value || undefined,
+        any_search: searchBar.value || undefined,
+    };
+
+    console.log("requestData",requestData);
+    // 发送 POST 请求到接口
+    fetch('http://127.0.0.1:8080/api/admin/GetConditionalSearch', {
+        method: 'POST',
+        headers: {
+            'Authorization': `Bearer ${authToken}`,
+            'Content-Type': 'application/json',
+        },
+        body: JSON.stringify(requestData),
+    })
+    .then(response => response.json())
+    .then(data => {
+        console.log('成功获取数据:', data);
+        // 处理返回的数据并更新界面
+        displayLicenseInfo(data.data);
+    })
+    .catch(error => {
+        console.error('获取数据时发生错误:', error);
+    });
+}
 
-        // 检查日期范围是否符合过滤条件
-        let matchesDate = true;
-        if (selectedStartDate) {
-            matchesDate = cardDate >= selectedStartDate;
-        }
-        if (selectedEndDate) {
-            matchesDate = matchesDate && cardDate <= selectedEndDate;
-        }
+// 处理并显示返回的 License 信息
+function displayLicenseInfo(data) {
+    // 清空之前的结果
+    licenseInfoContainer.innerHTML = '';
+    LicApplicationData =[];
+    // 遍历返回的数据,生成并插入卡片
+    data.forEach(item => {
+        const licInfo = item.LicInfo;
+        const genrateInfo = item.GenrateInfo;
+
+        // 创建卡片元素
+        const card = document.createElement('div');
+        card.classList.add('license-info-card');
+        card.innerHTML = `
+            <h3>${licInfo.oa_request_name.String}</h3>
+            <p>项目名称: ${licInfo.oa_glxm_name.String}</p>
+            <p>申请时间: ${licInfo.oa_sqsj.String}</p>
+            <p>状态: ${genrateInfo.license_flage.String}</p>
+            <p>License 生成时间: ${new Date(genrateInfo.creator_generate.Time).toLocaleString()}</p>
+        `;
 
-        // 显示符合所有过滤条件的卡片,隐藏不符合条件的卡片
-        if (matchesSearch && matchesStatus && matchesDate) {
-            card.style.display = '';  // 显示卡片
-        } else {
-            card.style.display = 'none';  // 隐藏卡片
-        }
+        // 将卡片插入容器
+        licenseInfoContainer.appendChild(card);
     });
 }
 
-

+ 73 - 0
static/role/role.css

@@ -0,0 +1,73 @@
+.role-info-cards-container {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 16px;
+    justify-content: flex-start;
+}
+
+.role-item {
+    background-color: #f9f9f9;
+    border-radius: 8px;
+    padding: 16px;
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+    width: 300px;
+    transition: transform 0.2s ease-in-out;
+    position: relative;
+}
+
+.role-item:hover {
+    transform: scale(1.05);
+}
+
+.role-info-create-role-button {
+    background-color: #007aff;
+    color: white;
+    border: none;
+    padding: 10px 20px;
+    border-radius: 10px;
+    cursor: pointer;
+    font-size: 16px;
+    font-weight: 500;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    transition: background-color 0.3s;
+    margin-left: 20px;
+}
+
+.role-info-create-role-button:hover {
+    background-color: #005bb5;
+}
+
+/* 弹出菜单样式 */
+#role-action-menu {
+    position: absolute;
+    background-color: #fff;
+    border: 1px solid #ccc;
+    border-radius: 5px;
+    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
+    padding: 10px;
+    z-index: 1000;
+}
+
+/* 模态框内按钮 */
+.role-info-button {
+    padding: 10px 20px;
+    background-color: #4CAF50;
+    color: white;
+    border: none;
+    border-radius: 4px;
+    cursor: pointer;
+    transition: background-color 0.3s;
+    margin-bottom: 10px;
+}
+
+.role-info-button:hover {
+    background-color: #45a049;
+}
+
+.role-info-button-delete {
+    background-color: #ff3b30;
+}
+
+.role-info-button-delete:hover {
+    background-color: #c23321;
+}

+ 13 - 23
static/role/role.html

@@ -1,38 +1,28 @@
-
-
-
 <!DOCTYPE html>
 <html lang="zh-CN">
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    
     <title>角色管理</title>
     <link rel="stylesheet" href="../role/role.css">
 </head>
 <body>
- 
-    <h2>用角色页面</h2>
-    <p>这是角色管理相关的内容。</p>
-   
 
+    <h2>角色管理页面</h2>
 
-    <!-- 新增的角色管理容器 -->
-    <div id="role-management" style="display: none;">
-        <div
-            style="display: flex; align-items: center; justify-content: space-between;">
-            <h2>角色管理</h2>
-            <button id="createRoleButton"
-                class="create-role-button">创建角色</button>
-        </div>
-        <div id="roles-container"></div>
+    <div id="roles-container" class="role-info-cards-container">
+        <!-- 角色将通过JS动态插入到这里 -->
     </div>
-    
-    
-    
-<script src="../role/role.js"></script>
 
-</body>
-</html>
+    <!-- 创建角色按钮,仅在有权限时显示 -->
+    <button id="createRoleButton" class="role-info-create-role-button" style="display: none;">创建角色</button>
 
+    <!-- 角色弹出菜单 -->
+    <div id="role-action-menu" class="role-info-modal" style="display: none;">
+        <!-- 通过JavaScript动态生成菜单内容 -->
+    </div>
+
+    <script src="role.js"></script>
 
+</body>
+</html>

+ 359 - 0
static/role/role.js

@@ -0,0 +1,359 @@
+// role.js
+
+
+
+
+
+// 页面加载时获取角色列表
+document.addEventListener('DOMContentLoaded', function() {
+    fetchRoles();
+
+    // 绑定创建角色按钮的点击事件
+    document.getElementById('createRoleButton').addEventListener('click', function() {
+        createRole();
+    });
+});
+
+fetchRoles()
+function fetchRoles() {
+    fetch('http://127.0.0.1:8080/api/admin/GetRoles', {
+        method: 'POST',
+        headers: {
+            'Authorization': `Bearer ${authToken}`,
+            'Content-Type': 'application/json'
+        },
+        body: JSON.stringify({ Name: " " })  // 发送空的 Name 参数
+    })
+    .then(response => response.json())
+    .then(data => {
+        const roleContainer = document.getElementById('roles-container');
+        roleContainer.innerHTML = ''; // 清空之前的内容
+
+        const permissionMap = {
+            'generate_license': '生成许可证',
+            'upload_license': '上传许可证(废弃)',
+            'read_license': '读取许可证',
+            'read_license_record': '读取许可证分发记录',
+            'update_license': '修改许可证(废弃)',
+            'delete_license': '删除许可证(废弃)',
+            'dispat_license': '分发许可证',
+            'create_user': '创建用户',
+            'read_user': '读取用户',
+            'update_user': '更新用户',
+            'delete_user': '删除用户',
+            'create_role': '创建角色',
+            'delete_role': '删除角色',
+            'update_role': '更新角色',
+            'get_role': '获取角色'
+        };
+
+        // 检查用户是否有 create_role 权限
+        const hasCreateRolePermission = currentUserPermissions.includes('create_role');
+
+        // 如果有权限则显示“创建角色”按钮
+        if (hasCreateRolePermission) {
+            document.getElementById('createRoleButton').style.display = 'block';
+        } else {
+            document.getElementById('createRoleButton').style.display = 'none';
+        }
+
+        // 处理置顶角色和其他角色的渲染
+        const topRoles = ['admin', 'guest', 'supportRole'];
+
+        topRoles.forEach(role => {
+            if (data.data[role]) {
+                renderRole(roleContainer, data.data[role], permissionMap, true);
+            }
+        });
+
+        Object.keys(data.data).forEach(role => {
+            if (!topRoles.includes(role)) {
+                renderRole(roleContainer, data.data[role], permissionMap, false);
+            }
+        });
+    })
+    .catch(error => {
+        console.error('获取角色数据失败:', error);
+    });
+}
+
+function renderRole(container, roleInfo, permissionMap, isTopRole) {
+    const roleDiv = document.createElement('div');
+    roleDiv.className = 'role-item';
+
+    if (isTopRole) {
+        roleDiv.classList.add('top-role'); // 应用置顶角色的样式
+    }
+
+    let permissions = roleInfo.Permissions.map(permission => permissionMap[permission] || permission);
+    let permissionsHtml = permissions.join(',');  // 使用逗号分隔并合并为一行
+
+    roleDiv.innerHTML = `
+        <h3>${roleInfo.Name}</h3>
+        <p>${permissionsHtml}</p>
+    `;
+    container.appendChild(roleDiv);
+
+    // 添加事件监听器,处理点击和右键点击弹出菜单
+    roleDiv.addEventListener('click', function(event) {
+        event.stopPropagation();  // 阻止事件冒泡
+        event.preventDefault();   // 阻止默认行为
+        showRoleActionMenu(event, roleInfo.Name);
+    });
+
+    roleDiv.addEventListener('contextmenu', function(event) {
+        event.preventDefault();
+        showRoleActionMenu(event, roleInfo.Name);
+    });
+}
+
+function showRoleActionMenu(event, roleName) {
+    // 移除已有的菜单
+    const existingMenu = document.getElementById('role-action-menu');
+    if (existingMenu) {
+        existingMenu.remove();
+    }
+
+    const menu = document.createElement('div');
+    menu.id = 'role-action-menu';
+    menu.className = 'role-action-menu';
+    menu.style.top = `${event.clientY}px`;
+    menu.style.left = `${event.clientX}px`;
+
+    const topRoles = ['admin', 'guest', 'supportRole'];
+
+    if (topRoles.includes(roleName)) {
+        // 为置顶角色设置不可操作的提示
+        const disabledButton = document.createElement('button');
+        disabledButton.textContent = '不可操作';
+        disabledButton.className = 'role-info-button-disabled';
+        menu.appendChild(disabledButton);
+    } else {
+        // 检查用户是否有 update_role 和 delete_role 权限
+        const hasUpdateRolePermission = currentUserPermissions.includes('update_role');
+        const hasDeleteRolePermission = currentUserPermissions.includes('delete_role');
+
+        // 创建和添加修改角色按钮
+        if (hasUpdateRolePermission) {
+            const modifyButton = document.createElement('button');
+            modifyButton.textContent = '修改角色';
+            modifyButton.className = 'role-info-button';
+            modifyButton.addEventListener('click', function () {
+                modifyRole(roleName);
+                menu.remove(); // 点击按钮后,关闭菜单栏
+            });
+            menu.appendChild(modifyButton);
+        }
+
+        // 创建和添加删除角色按钮
+        if (hasDeleteRolePermission) {
+            const deleteButton = document.createElement('button');
+            deleteButton.textContent = '删除角色';
+            deleteButton.className = 'role-info-button role-info-button-delete';
+            deleteButton.addEventListener('click', function () {
+                deleteRole(roleName);
+                menu.remove(); // 点击按钮后,关闭菜单栏
+            });
+            menu.appendChild(deleteButton);
+        }
+
+        // 如果用户没有修改或删除权限,则显示没有可用操作
+        if (!hasUpdateRolePermission && !hasDeleteRolePermission) {
+            const noOption = document.createElement('div');
+            noOption.textContent = '没有可用的操作';
+            noOption.style.textAlign = 'center';
+            noOption.style.color = '#999';
+            menu.appendChild(noOption);
+        }
+    }
+
+    document.body.appendChild(menu);
+
+    // 点击其他地方关闭菜单
+    document.addEventListener('click', function closeMenu(event) {
+        if (!menu.contains(event.target)) {
+            menu.remove();
+            document.removeEventListener('click', closeMenu);
+        }
+    });
+}
+
+//修改角色信息
+function modifyRole(roleName) {
+    console.log(`modifyRole called with roleName: ${roleName}`);
+    
+    fetchRoleInfo(roleName, function(roleInfo) {
+        console.log(`fetchRoleInfo returned:`, roleInfo);
+
+        if (!roleInfo) {
+            console.error('Role info is undefined or null');
+            return;
+        }
+
+        const extraInfoContent = document.getElementById('extraInfoContent');
+        if (!extraInfoContent) {
+            console.error('Element with id "extraInfoContent" not found');
+            return;
+        }
+
+        extraInfoContent.innerHTML = `
+            <h3>修改角色: ${roleInfo.Name}</h3>
+            <label for="roleName">角色名称:</label>
+            <input type="text" id="roleName" value="${roleInfo.Name}" required><br><br>
+            <label for="permissions">权限:</label><br>
+            <div id="permissions">
+                  <div>
+            <input type="checkbox" id="license" name="permissions" value="license" onchange="toggleSubPermissions('license', this)">
+            <label for="license">许可证</label>
+            <div id="licenseSubPermissions" style="margin-left: 20px;">
+                <input type="checkbox" id="generate_license" name="permissions" value="generate_license">
+                <label for="generate_license">生成许可证</label><br>
+                <input type="checkbox" id="upload_license" name="permissions" value="upload_license">
+                <label for="upload_license">上传许可证</label><br>
+                <input type="checkbox" id="read_license" name="permissions" value="read_license">
+                <label for="read_license">读取许可证</label><br>
+                <input type="checkbox" id="update_license" name="permissions" value="update_license">
+                <label for="update_license">更新许可证</label><br>
+                <input type="checkbox" id="delete_license" name="permissions" value="delete_license">
+                <label for="delete_license">删除许可证</label><br>
+            </div>
+        </div>
+        <div>
+            <input type="checkbox" id="user" name="permissions" value="user" onchange="toggleSubPermissions('user', this)">
+            <label for="user">用户</label>
+            <div id="userSubPermissions" style="margin-left: 20px;">
+                <input type="checkbox" id="create_user" name="permissions" value="create_user">
+                <label for="create_user">创建用户</label><br>
+                <input type="checkbox" id="read_user" name="permissions" value="read_user">
+                <label for="read_user">读取用户</label><br>
+                <input type="checkbox" id="update_user" name="permissions" value="update_user">
+                <label for="update_user">更新用户</label><br>
+                <input type="checkbox" id="delete_user" name="permissions" value="delete_user">
+                <label for="delete_user">删除用户</label><br>
+            </div>
+        </div>
+        <div>
+            <input type="checkbox" id="role" name="permissions" value="role" onchange="toggleSubPermissions('role', this)">
+            <label for="role">角色</label>
+            <div id="roleSubPermissions" style="margin-left: 20px;">
+                <input type="checkbox" id="create_role" name="permissions" value="create_role">
+                <label for="create_role">创建角色</label><br>
+                <input type="checkbox" id="delete_role" name="permissions" value="delete_role">
+                <label for="delete_role">删除角色</label><br>
+                <input type="checkbox" id="update_role" name="permissions" value="update_role">
+                <label for="update_role">更新角色</label><br>
+                <input type="checkbox" id="get_role" name="permissions" value="get_role">
+                <label for="get_role">获取角色</label><br>
+            </div>
+        </div>
+            </div><br><br>
+            <button onclick="saveRoleChanges('${roleInfo.Id}')">保存</button>
+        `;
+
+        console.log('Form content added to extraInfoContent');
+
+        const checkboxes = document.querySelectorAll('#permissions input[type="checkbox"]');
+
+// 遍历所有复选框
+checkboxes.forEach(checkbox => {
+    if (roleInfo.Permissions.includes(checkbox.value)) {
+        checkbox.checked = true; // 如果当前权限在roleInfo.Permissions中,则勾选
+    }
+});
+
+        const extraInfoModal = document.getElementById('extraInfoModal');
+        if (!extraInfoModal) {
+            console.error('Element with id "extraInfoModal" not found');
+            return;
+        }
+
+        extraInfoModal.style.display = 'block';  // 强制显示模态框
+        console.log('Modal should be visible now');
+    });
+}
+
+
+// 示例的删除角色函数
+function deleteRole(roleName) {
+    if (confirm(`确定要删除角色:${roleName} 吗?`)) {
+        fetch('http://127.0.0.1:8080/api/admin/DeleteRole', {
+            method: 'POST',
+            headers: {
+                'Authorization': `Bearer ${authToken}`,
+                'Content-Type': 'application/json'
+            },
+            body: JSON.stringify({ Name: roleName })
+        })
+        .then(response => response.json())
+        .then(data => {
+            if (data.code === 200) {
+                alert('角色删除成功');
+                fetchRoles(); // 重新获取角色列表
+            } else {
+                alert(`删除失败:${data.message}`);
+            }
+        })
+        .catch(error => {
+            console.error('删除角色出错:', error);
+        });
+    }
+}
+
+
+function showCreateRoleModal() {
+    const extraInfoContent = document.getElementById('extraInfoContent');
+    extraInfoContent.innerHTML = `
+        <h3>创建新角色</h3>
+        <label for="newRoleName">角色名称:</label>
+        <input type="text" id="newRoleName" required><br><br>
+        <label for="newPermissions">权限:</label><br>
+        <div id="newPermissions">
+            <div>
+                <input type="checkbox" id="license" name="permissions" value="license" onchange="toggleSubPermissions('license', this)">
+                <label for="license">许可证</label>
+                <div id="licenseSubPermissions" style="margin-left: 20px;">
+                    <input type="checkbox" id="generate_license" name="permissions" value="generate_license">
+                    <label for="generate_license">生成许可证</label><br>
+                    <input type="checkbox" id="upload_license" name="permissions" value="upload_license">
+                    <label for="upload_license">上传许可证(废弃)</label><br>
+                    <input type="checkbox" id="read_license" name="permissions" value="read_license">
+                    <label for="read_license">读取许可证</label><br>
+                    <input type="checkbox" id="update_license" name="permissions" value="update_license">
+                    <label for="update_license">更新许可证(废弃)</label><br>
+                    <input type="checkbox" id="delete_license" name="permissions" value="delete_license">
+                    <label for="delete_license">删除许可证(废弃)</label><br>
+                </div>
+            </div>
+            <div>
+                <input type="checkbox" id="user" name="permissions" value="user" onchange="toggleSubPermissions('user', this)">
+                <label for="user">用户</label>
+                <div id="userSubPermissions" style="margin-left: 20px;">
+                    <input type="checkbox" id="create_user" name="permissions" value="create_user">
+                    <label for="create_user">创建用户</label><br>
+                    <input type="checkbox" id="read_user" name="permissions" value="read_user">
+                    <label for="read_user">读取用户</label><br>
+                    <input type="checkbox" id="update_user" name="permissions" value="update_user">
+                    <label for="update_user">更新用户</label><br>
+                    <input type="checkbox" id="delete_user" name="permissions" value="delete_user">
+                    <label for="delete_user">删除用户</label><br>
+                </div>
+            </div>
+            <div>
+                <input type="checkbox" id="role" name="permissions" value="role" onchange="toggleSubPermissions('role', this)">
+                <label for="role">角色</label>
+                <div id="roleSubPermissions" style="margin-left: 20px;">
+                    <input type="checkbox" id="create_role" name="permissions" value="create_role">
+                    <label for="create_role">创建角色</label><br>
+                    <input type="checkbox" id="delete_role" name="permissions" value="delete_role">
+                    <label for="delete_role">删除角色</label><br>
+                    <input type="checkbox" id="update_role" name="permissions" value="update_role">
+                    <label for="update_role">更新角色</label><br>
+                    <input type="checkbox" id="get_role" name="permissions" value="get_role">
+                    <label for="get_role">获取角色</label><br>
+                </div>
+            </div>
+        </div><br><br>
+        <button onclick="createNewRole()">创建</button>
+    `;
+    document.getElementById('extraInfoModal').style.display = 'block';
+}