| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  | <!DOCTYPE html> | 
					
						
							|  |  |  | <html lang="zh-CN"> | 
					
						
							|  |  |  | <head> | 
					
						
							|  |  |  |     <meta charset="UTF-8"> | 
					
						
							|  |  |  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |     <title>权限编辑</title> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |     <style> | 
					
						
							|  |  |  |         * { | 
					
						
							|  |  |  |             margin: 0; | 
					
						
							|  |  |  |             padding: 0; | 
					
						
							|  |  |  |             box-sizing: border-box; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         body { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif; | 
					
						
							|  |  |  |             background-color: #f5f5f5; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             color: #333; | 
					
						
							|  |  |  |             height: 100vh; | 
					
						
							| 
									
										
										
										
											2025-09-06 02:33:10 +00:00
										 |  |  |             margin: 0; | 
					
						
							|  |  |  |             padding: 0; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .container { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             max-width: 1600px; | 
					
						
							|  |  |  |             margin: 0 auto; | 
					
						
							|  |  |  |             padding: 20px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         /* 页面头部 */ | 
					
						
							|  |  |  |         .page-header { | 
					
						
							|  |  |  |             background: white; | 
					
						
							|  |  |  |             padding: 16px 24px; | 
					
						
							|  |  |  |             margin-bottom: 16px; | 
					
						
							|  |  |  |             border-radius: 8px; | 
					
						
							|  |  |  |             box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             display: flex; | 
					
						
							|  |  |  |             justify-content: space-between; | 
					
						
							|  |  |  |             align-items: center; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .page-title { | 
					
						
							|  |  |  |             font-size: 24px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-weight: 600; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #262626; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         /* 按钮样式 */ | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         .btn { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             height: 40px; | 
					
						
							|  |  |  |             padding: 0 16px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             border: none; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border-radius: 6px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-size: 14px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             cursor: pointer; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             display: inline-flex; | 
					
						
							|  |  |  |             align-items: center; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             justify-content: center; | 
					
						
							|  |  |  |             transition: all 0.3s; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             gap: 5px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .btn-primary { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #1890ff; | 
					
						
							|  |  |  |             color: white; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .btn-primary:hover { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #40a9ff; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .btn-success { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #52c41a; | 
					
						
							|  |  |  |             color: white; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .btn-success:hover { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #73d13d; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .btn-danger { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #ff4d4f; | 
					
						
							|  |  |  |             color: white; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .btn-danger:hover { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #ff7875; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .btn-default { | 
					
						
							|  |  |  |             background: white; | 
					
						
							|  |  |  |             color: #666; | 
					
						
							|  |  |  |             border: 1px solid #ddd; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .btn-default:hover { | 
					
						
							|  |  |  |             border-color: #1890ff; | 
					
						
							|  |  |  |             color: #1890ff; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .btn-sm { | 
					
						
							|  |  |  |             height: 32px; | 
					
						
							|  |  |  |             padding: 0 12px; | 
					
						
							|  |  |  |             font-size: 12px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .button-group { | 
					
						
							|  |  |  |             display: flex; | 
					
						
							|  |  |  |             gap: 12px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* 搜索区域 */ | 
					
						
							|  |  |  |         .search-section { | 
					
						
							|  |  |  |             background: white; | 
					
						
							|  |  |  |             padding: 24px; | 
					
						
							|  |  |  |             margin-bottom: 16px; | 
					
						
							|  |  |  |             border-radius: 8px; | 
					
						
							|  |  |  |             box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .search-form { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             display: grid; | 
					
						
							|  |  |  |             grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | 
					
						
							|  |  |  |             gap: 16px; | 
					
						
							|  |  |  |             margin-bottom: 16px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .form-item { | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             display: flex; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             flex-direction: column; | 
					
						
							|  |  |  |             gap: 8px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .form-label { | 
					
						
							|  |  |  |             font-size: 14px; | 
					
						
							|  |  |  |             color: #666; | 
					
						
							|  |  |  |             font-weight: 500; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .form-input { | 
					
						
							|  |  |  |             height: 40px; | 
					
						
							|  |  |  |             padding: 0 12px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             border: 1px solid #ddd; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border-radius: 6px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-size: 14px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .form-input:focus { | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             outline: none; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border-color: #1890ff; | 
					
						
							|  |  |  |             box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* 表格样式 */ | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .table-section { | 
					
						
							|  |  |  |             background: white; | 
					
						
							|  |  |  |             border-radius: 8px; | 
					
						
							|  |  |  |             box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | 
					
						
							|  |  |  |             overflow: hidden; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .table-wrapper { | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             overflow-x: auto; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permissions-table { | 
					
						
							|  |  |  |             width: 100%; | 
					
						
							|  |  |  |             border-collapse: collapse; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             font-size: 14px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .permissions-table th { | 
					
						
							|  |  |  |             background: #fafafa; | 
					
						
							|  |  |  |             padding: 12px 16px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             text-align: left; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             font-weight: 600; | 
					
						
							|  |  |  |             color: #666; | 
					
						
							|  |  |  |             border-bottom: 1px solid #f0f0f0; | 
					
						
							|  |  |  |             white-space: nowrap; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .permissions-table td { | 
					
						
							|  |  |  |             padding: 12px 16px; | 
					
						
							|  |  |  |             border-bottom: 1px solid #f9f9f9; | 
					
						
							|  |  |  |             vertical-align: top; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .permissions-table tbody tr:hover { | 
					
						
							|  |  |  |             background: #f8f9fa; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-row { | 
					
						
							|  |  |  |             cursor: pointer; | 
					
						
							|  |  |  |             transition: background-color 0.2s ease; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-row.parent-row { | 
					
						
							|  |  |  |             font-weight: 500; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-row.child-row { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background-color: #fafafa; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |         .permission-row.level-1 td:first-child { | 
					
						
							|  |  |  |             padding-left: 60px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             position: relative; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |         .permission-row.level-1 td:first-child::before { | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             content: "└─"; | 
					
						
							|  |  |  |             position: absolute; | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             left: 35px; | 
					
						
							|  |  |  |             color: #bdc3c7; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-row.level-2 td:first-child { | 
					
						
							|  |  |  |             padding-left: 100px; | 
					
						
							|  |  |  |             position: relative; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-row.level-2 td:first-child::before { | 
					
						
							|  |  |  |             content: "└─"; | 
					
						
							|  |  |  |             position: absolute; | 
					
						
							|  |  |  |             left: 75px; | 
					
						
							|  |  |  |             color: #bdc3c7; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-row.level-3 td:first-child { | 
					
						
							|  |  |  |             padding-left: 140px; | 
					
						
							|  |  |  |             position: relative; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-row.level-3 td:first-child::before { | 
					
						
							|  |  |  |             content: "└─"; | 
					
						
							|  |  |  |             position: absolute; | 
					
						
							|  |  |  |             left: 115px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             color: #bdc3c7; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-code { | 
					
						
							|  |  |  |             font-family: monospace; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background-color: #f0f0f0; | 
					
						
							|  |  |  |             padding: 4px 8px; | 
					
						
							|  |  |  |             border-radius: 4px; | 
					
						
							|  |  |  |             font-size: 12px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .permission-type { | 
					
						
							|  |  |  |             padding: 4px 8px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border-radius: 4px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-size: 12px; | 
					
						
							|  |  |  |             font-weight: 500; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .type-menu { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #e6f7ff; | 
					
						
							|  |  |  |             color: #1890ff; | 
					
						
							|  |  |  |             border: 1px solid #91d5ff; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .type-button { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #f6ffed; | 
					
						
							|  |  |  |             color: #52c41a; | 
					
						
							|  |  |  |             border: 1px solid #b7eb8f; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .expand-btn { | 
					
						
							|  |  |  |             background: none; | 
					
						
							|  |  |  |             border: none; | 
					
						
							|  |  |  |             cursor: pointer; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             padding: 4px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             margin-right: 8px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #1890ff; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-size: 12px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             transition: all 0.3s; | 
					
						
							|  |  |  |             border-radius: 4px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .expand-btn:hover { | 
					
						
							|  |  |  |             background: #e6f7ff; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .expand-btn.collapsed { | 
					
						
							|  |  |  |             transform: rotate(-90deg); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .actions { | 
					
						
							|  |  |  |             display: flex; | 
					
						
							|  |  |  |             gap: 5px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* 弹窗样式 */ | 
					
						
							|  |  |  |         .modal { | 
					
						
							|  |  |  |             display: none; | 
					
						
							|  |  |  |             position: fixed; | 
					
						
							|  |  |  |             z-index: 1000; | 
					
						
							|  |  |  |             left: 0; | 
					
						
							|  |  |  |             top: 0; | 
					
						
							|  |  |  |             width: 100%; | 
					
						
							|  |  |  |             height: 100%; | 
					
						
							|  |  |  |             background-color: rgba(0, 0, 0, 0.5); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .modal.show { | 
					
						
							|  |  |  |             display: flex; | 
					
						
							|  |  |  |             align-items: center; | 
					
						
							|  |  |  |             justify-content: center; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .modal-content { | 
					
						
							|  |  |  |             background-color: #fff; | 
					
						
							|  |  |  |             border-radius: 8px; | 
					
						
							|  |  |  |             width: 500px; | 
					
						
							|  |  |  |             max-width: 90vw; | 
					
						
							|  |  |  |             max-height: 90vh; | 
					
						
							|  |  |  |             overflow-y: auto; | 
					
						
							|  |  |  |             box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); | 
					
						
							|  |  |  |             transform: scale(0.8); | 
					
						
							|  |  |  |             transition: transform 0.3s ease; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .modal.show .modal-content { | 
					
						
							|  |  |  |             transform: scale(1); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .modal-header { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background: #fafafa; | 
					
						
							|  |  |  |             padding: 16px 24px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             display: flex; | 
					
						
							|  |  |  |             justify-content: space-between; | 
					
						
							|  |  |  |             align-items: center; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border-bottom: 1px solid #f0f0f0; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .modal-header h3 { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             font-size: 18px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-weight: 600; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #262626; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .close { | 
					
						
							|  |  |  |             background: none; | 
					
						
							|  |  |  |             border: none; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #666; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-size: 24px; | 
					
						
							|  |  |  |             cursor: pointer; | 
					
						
							|  |  |  |             padding: 0; | 
					
						
							|  |  |  |             width: 30px; | 
					
						
							|  |  |  |             height: 30px; | 
					
						
							|  |  |  |             display: flex; | 
					
						
							|  |  |  |             align-items: center; | 
					
						
							|  |  |  |             justify-content: center; | 
					
						
							|  |  |  |             border-radius: 50%; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             transition: all 0.3s; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .close:hover { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background-color: #f0f0f0; | 
					
						
							|  |  |  |             color: #333; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .modal-body { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             padding: 24px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .form-group { | 
					
						
							|  |  |  |             margin-bottom: 20px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .form-group label { | 
					
						
							|  |  |  |             display: block; | 
					
						
							|  |  |  |             margin-bottom: 8px; | 
					
						
							|  |  |  |             font-weight: 500; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #333; | 
					
						
							|  |  |  |             font-size: 14px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .form-group input, | 
					
						
							|  |  |  |         .form-group select, | 
					
						
							|  |  |  |         .form-group textarea { | 
					
						
							|  |  |  |             width: 100%; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             padding: 10px 12px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             border: 1px solid #ddd; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border-radius: 6px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             font-size: 14px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             transition: all 0.3s; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .form-group input:focus, | 
					
						
							|  |  |  |         .form-group select:focus, | 
					
						
							|  |  |  |         .form-group textarea:focus { | 
					
						
							|  |  |  |             outline: none; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border-color: #1890ff; | 
					
						
							|  |  |  |             box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .form-group textarea { | 
					
						
							|  |  |  |             resize: vertical; | 
					
						
							|  |  |  |             min-height: 80px; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         .form-group small { | 
					
						
							|  |  |  |             color: #666; | 
					
						
							|  |  |  |             font-size: 12px; | 
					
						
							|  |  |  |             margin-top: 4px; | 
					
						
							|  |  |  |             display: block; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         .modal-footer { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             background-color: #fafafa; | 
					
						
							|  |  |  |             padding: 12px 24px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             display: flex; | 
					
						
							|  |  |  |             justify-content: flex-end; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             gap: 12px; | 
					
						
							|  |  |  |             border-top: 1px solid #f0f0f0; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* 右键菜单样式 */ | 
					
						
							|  |  |  |         .context-menu { | 
					
						
							|  |  |  |             position: fixed; | 
					
						
							|  |  |  |             background-color: #fff; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             border: 1px solid #f0f0f0; | 
					
						
							|  |  |  |             border-radius: 6px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); | 
					
						
							|  |  |  |             z-index: 2000; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             padding: 4px 0; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             min-width: 120px; | 
					
						
							|  |  |  |             display: none; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .context-menu-item { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             padding: 8px 16px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             cursor: pointer; | 
					
						
							|  |  |  |             font-size: 14px; | 
					
						
							|  |  |  |             transition: background-color 0.2s ease; | 
					
						
							|  |  |  |             display: flex; | 
					
						
							|  |  |  |             align-items: center; | 
					
						
							|  |  |  |             gap: 8px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #333; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .context-menu-item:hover { | 
					
						
							|  |  |  |             background-color: #f8f9fa; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* 空状态样式 */ | 
					
						
							|  |  |  |         .empty-state { | 
					
						
							|  |  |  |             text-align: center; | 
					
						
							|  |  |  |             padding: 60px 20px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #999; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .empty-state h3 { | 
					
						
							|  |  |  |             margin-bottom: 10px; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             color: #666; | 
					
						
							|  |  |  |             font-size: 16px; | 
					
						
							|  |  |  |             font-weight: 500; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         .empty-state p { | 
					
						
							|  |  |  |             font-size: 14px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* 响应式设计 */ | 
					
						
							|  |  |  |         @media (max-width: 768px) { | 
					
						
							|  |  |  |             .container { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 padding: 10px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             .page-header { | 
					
						
							|  |  |  |                 padding: 12px 16px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 flex-direction: column; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 gap: 12px; | 
					
						
							|  |  |  |                 align-items: flex-start; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             .search-section { | 
					
						
							|  |  |  |                 padding: 16px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             .permissions-table { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 font-size: 12px; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             .permissions-table th, | 
					
						
							|  |  |  |             .permissions-table td { | 
					
						
							|  |  |  |                 padding: 8px 10px; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             .modal-content { | 
					
						
							|  |  |  |                 width: 95vw; | 
					
						
							|  |  |  |                 margin: 10px; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     </style> | 
					
						
							|  |  |  | </head> | 
					
						
							|  |  |  | <body> | 
					
						
							|  |  |  |     <div class="container"> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         <!-- 页面头部 --> | 
					
						
							|  |  |  |         <div class="page-header"> | 
					
						
							|  |  |  |             <h1 class="page-title">权限编辑</h1> | 
					
						
							|  |  |  |             <div class="button-group"> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 <button class="btn btn-success" onclick="openAddModal()"> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                     新增权限 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 </button> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         <!-- 搜索区域 --> | 
					
						
							|  |  |  |         <div class="search-section"> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             <div class="search-form"> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 <div class="form-item"> | 
					
						
							|  |  |  |                     <input type="text" class="form-input" id="searchInput" placeholder="搜索权限编码、名称或描述..."> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |             <div class="button-group"> | 
					
						
							|  |  |  |                 <button class="btn btn-primary" onclick="searchPermissions()">搜索</button> | 
					
						
							|  |  |  |                 <button class="btn btn-default" onclick="resetSearch()">重置</button> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |         <!-- 表格区域 --> | 
					
						
							|  |  |  |         <div class="table-section"> | 
					
						
							|  |  |  |             <div class="table-wrapper"> | 
					
						
							|  |  |  |                 <table class="permissions-table"> | 
					
						
							|  |  |  |                     <thead> | 
					
						
							|  |  |  |                         <tr> | 
					
						
							|  |  |  |                             <th>权限编码</th> | 
					
						
							|  |  |  |                             <th>权限名称</th> | 
					
						
							|  |  |  |                             <th>权限描述</th> | 
					
						
							|  |  |  |                             <th>权限类型</th> | 
					
						
							|  |  |  |                             <th>父级权限</th> | 
					
						
							|  |  |  |                             <th>可见身份</th> | 
					
						
							|  |  |  |                             <th>操作</th> | 
					
						
							|  |  |  |                         </tr> | 
					
						
							|  |  |  |                     </thead> | 
					
						
							|  |  |  |                     <tbody id="permissionsTableBody"> | 
					
						
							|  |  |  |                         <!-- 数据将通过JavaScript动态加载 --> | 
					
						
							|  |  |  |                     </tbody> | 
					
						
							|  |  |  |                 </table> | 
					
						
							|  |  |  |                 <div class="empty-state" id="emptyState" style="display: none;"> | 
					
						
							|  |  |  |                     <h3>暂无权限数据</h3> | 
					
						
							|  |  |  |                     <p>点击"新增权限"按钮开始添加权限信息</p> | 
					
						
							|  |  |  |                 </div> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <!-- 权限弹窗 --> | 
					
						
							|  |  |  |     <div id="permissionModal" class="modal"> | 
					
						
							|  |  |  |         <div class="modal-content"> | 
					
						
							|  |  |  |             <div class="modal-header"> | 
					
						
							|  |  |  |                 <h3 id="modalTitle">新增权限</h3> | 
					
						
							|  |  |  |                 <button type="button" class="close" onclick="closeModal()">×</button> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |             <div class="modal-body"> | 
					
						
							|  |  |  |                 <form id="permissionForm"> | 
					
						
							|  |  |  |                     <div class="form-group"> | 
					
						
							|  |  |  |                         <label for="permissionCode">权限编码 *</label> | 
					
						
							|  |  |  |                         <input type="text" id="permissionCode" name="code" required placeholder="请输入全局唯一的权限编码"> | 
					
						
							|  |  |  |                     </div> | 
					
						
							|  |  |  |                     <div class="form-group"> | 
					
						
							|  |  |  |                         <label for="permissionName">权限名称 *</label> | 
					
						
							|  |  |  |                         <input type="text" id="permissionName" name="name" required placeholder="请输入权限名称"> | 
					
						
							|  |  |  |                     </div> | 
					
						
							|  |  |  |                     <div class="form-group"> | 
					
						
							|  |  |  |                         <label for="permissionDesc">权限描述</label> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                         <textarea id="permissionDesc" name="description" placeholder="请输入权限描述(可选)"></textarea> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                     </div> | 
					
						
							|  |  |  |                     <div class="form-group"> | 
					
						
							|  |  |  |                         <label for="parentCode">父级权限编码</label> | 
					
						
							|  |  |  |                         <select id="parentCode" name="parentCode"> | 
					
						
							|  |  |  |                             <option value="">无父级权限</option> | 
					
						
							|  |  |  |                             <!-- 选项将通过JavaScript动态加载 --> | 
					
						
							|  |  |  |                         </select> | 
					
						
							|  |  |  |                     </div> | 
					
						
							|  |  |  |                     <div class="form-group"> | 
					
						
							|  |  |  |                         <label for="permissionType">权限类型 *</label> | 
					
						
							|  |  |  |                         <select id="permissionType" name="type" required> | 
					
						
							|  |  |  |                             <option value="">请选择权限类型</option> | 
					
						
							|  |  |  |                             <option value="menu">菜单</option> | 
					
						
							|  |  |  |                             <option value="button">按钮</option> | 
					
						
							|  |  |  |                         </select> | 
					
						
							|  |  |  |                     </div> | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     <div class="form-group"> | 
					
						
							|  |  |  |                         <label for="visibleRoles">可见身份</label> | 
					
						
							|  |  |  |                         <select id="visibleRoles" name="visibleRoles" multiple size="5"> | 
					
						
							|  |  |  |                             <option value="经营者">经营者</option> | 
					
						
							|  |  |  |                             <option value="商户">商户</option> | 
					
						
							|  |  |  |                             <option value="代理商">代理商</option> | 
					
						
							|  |  |  |                             <option value="分销商">分销商</option> | 
					
						
							|  |  |  |                             <option value="品牌管理员">品牌管理员</option> | 
					
						
							|  |  |  |                         </select> | 
					
						
							|  |  |  |                         <small>按住 Ctrl 键可多选</small> | 
					
						
							|  |  |  |                     </div> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 </form> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |             <div class="modal-footer"> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 <button type="button" class="btn btn-default" onclick="closeModal()">取消</button> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 <button type="button" class="btn btn-success" onclick="savePermission()">保存</button> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <!-- 右键菜单 --> | 
					
						
							|  |  |  |     <div id="contextMenu" class="context-menu"> | 
					
						
							|  |  |  |         <div class="context-menu-item" onclick="addChildPermission()"> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             添加子权限 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         </div> | 
					
						
							|  |  |  |         <div class="context-menu-item" onclick="editPermission()"> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             编辑权限 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         </div> | 
					
						
							|  |  |  |         <div class="context-menu-item" onclick="deletePermission()"> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |             删除权限 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <script> | 
					
						
							|  |  |  |         // 权限数据存储 | 
					
						
							|  |  |  |         let permissions = []; | 
					
						
							|  |  |  |         let currentEditingId = null; | 
					
						
							|  |  |  |         let contextMenuTargetRow = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 初始化示例数据 | 
					
						
							|  |  |  |         function initSampleData() { | 
					
						
							|  |  |  |             permissions = [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     id: 1, | 
					
						
							|  |  |  |                     code: 'SYSTEM', | 
					
						
							|  |  |  |                     name: '系统管理', | 
					
						
							|  |  |  |                     description: '系统管理模块', | 
					
						
							|  |  |  |                     parentCode: '', | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     type: 'menu', | 
					
						
							|  |  |  |                     visibleRoles: ['经营者', '商户', '代理商'] | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     id: 2, | 
					
						
							|  |  |  |                     code: 'SYSTEM_USER', | 
					
						
							|  |  |  |                     name: '用户管理', | 
					
						
							|  |  |  |                     description: '用户管理功能', | 
					
						
							|  |  |  |                     parentCode: 'SYSTEM', | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     type: 'menu', | 
					
						
							|  |  |  |                     visibleRoles: ['经营者', '商户'] | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     id: 3, | 
					
						
							|  |  |  |                     code: 'SYSTEM_USER_ADD', | 
					
						
							|  |  |  |                     name: '添加用户', | 
					
						
							|  |  |  |                     description: '添加新用户按钮', | 
					
						
							|  |  |  |                     parentCode: 'SYSTEM_USER', | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     type: 'button', | 
					
						
							|  |  |  |                     visibleRoles: ['经营者'] | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     id: 4, | 
					
						
							|  |  |  |                     code: 'SYSTEM_USER_EDIT', | 
					
						
							|  |  |  |                     name: '编辑用户', | 
					
						
							|  |  |  |                     description: '编辑用户信息按钮', | 
					
						
							|  |  |  |                     parentCode: 'SYSTEM_USER', | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     type: 'button', | 
					
						
							|  |  |  |                     visibleRoles: ['经营者', '代理商'] | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     id: 5, | 
					
						
							|  |  |  |                     code: 'SYSTEM_ROLE', | 
					
						
							|  |  |  |                     name: '角色管理', | 
					
						
							|  |  |  |                     description: '角色管理功能', | 
					
						
							|  |  |  |                     parentCode: 'SYSTEM', | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     type: 'menu', | 
					
						
							|  |  |  |                     visibleRoles: ['经营者'] | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     id: 6, | 
					
						
							|  |  |  |                     code: 'CONTENT', | 
					
						
							|  |  |  |                     name: '内容管理', | 
					
						
							|  |  |  |                     description: '内容管理模块', | 
					
						
							|  |  |  |                     parentCode: '', | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     type: 'menu', | 
					
						
							|  |  |  |                     visibleRoles: ['商户', '代理商', '分销商'] | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |             renderPermissionsTable(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 渲染权限表格 | 
					
						
							|  |  |  |         function renderPermissionsTable(data = permissions) { | 
					
						
							|  |  |  |             const tableBody = document.getElementById('permissionsTableBody'); | 
					
						
							|  |  |  |             const emptyState = document.getElementById('emptyState'); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             if (data.length === 0) { | 
					
						
							|  |  |  |                 tableBody.innerHTML = ''; | 
					
						
							|  |  |  |                 emptyState.style.display = 'block'; | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             emptyState.style.display = 'none'; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             // 构建树状结构 | 
					
						
							|  |  |  |             const tree = buildPermissionTree(data); | 
					
						
							|  |  |  |             let html = ''; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             tree.forEach(item => { | 
					
						
							|  |  |  |                 html += renderPermissionRow(item, 0); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             tableBody.innerHTML = html; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 构建权限树 | 
					
						
							|  |  |  |         function buildPermissionTree(data) { | 
					
						
							|  |  |  |             const map = {}; | 
					
						
							|  |  |  |             const roots = []; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             // 创建映射 | 
					
						
							|  |  |  |             data.forEach(item => { | 
					
						
							|  |  |  |                 map[item.code] = { ...item, children: [] }; | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             // 构建树结构 | 
					
						
							|  |  |  |             data.forEach(item => { | 
					
						
							|  |  |  |                 if (item.parentCode && map[item.parentCode]) { | 
					
						
							|  |  |  |                     map[item.parentCode].children.push(map[item.code]); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     roots.push(map[item.code]); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             return roots; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 渲染权限行 | 
					
						
							|  |  |  |         function renderPermissionRow(item, level) { | 
					
						
							|  |  |  |             const hasChildren = item.children && item.children.length > 0; | 
					
						
							|  |  |  |             const isParent = level === 0; | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             let rowClass = 'permission-row'; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             if (isParent) { | 
					
						
							|  |  |  |                 rowClass += ' parent-row'; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 rowClass += ' child-row level-' + level; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             let html = ` | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 <tr class="${rowClass}" | 
					
						
							|  |  |  |                     data-id="${item.id}" | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                     data-code="${item.code}" | 
					
						
							|  |  |  |                     oncontextmenu="showContextMenu(event, this)"> | 
					
						
							|  |  |  |                     <td> | 
					
						
							|  |  |  |                         ${hasChildren ? `<button class="expand-btn" onclick="toggleChildren(this)">▼</button>` : ''} | 
					
						
							|  |  |  |                         <span class="permission-code">${item.code}</span> | 
					
						
							|  |  |  |                     </td> | 
					
						
							|  |  |  |                     <td>${item.name}</td> | 
					
						
							|  |  |  |                     <td>${item.description || '-'}</td> | 
					
						
							|  |  |  |                     <td><span class="permission-type type-${item.type}">${item.type === 'menu' ? '菜单' : '按钮'}</span></td> | 
					
						
							|  |  |  |                     <td>${item.parentCode || '-'}</td> | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                     <td>${item.visibleRoles ? item.visibleRoles.join(', ') : '-'}</td> | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                     <td class="actions"> | 
					
						
							|  |  |  |                         <button class="btn btn-primary btn-sm" onclick="editPermissionById(${item.id})">编辑</button> | 
					
						
							|  |  |  |                         <button class="btn btn-danger btn-sm" onclick="deletePermissionById(${item.id})">删除</button> | 
					
						
							|  |  |  |                     </td> | 
					
						
							|  |  |  |                 </tr> | 
					
						
							|  |  |  |             `; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             // 添加子权限行 | 
					
						
							|  |  |  |             if (hasChildren) { | 
					
						
							|  |  |  |                 item.children.forEach(child => { | 
					
						
							|  |  |  |                     html += renderPermissionRow(child, level + 1); | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             return html; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 展开/收起子权限 | 
					
						
							|  |  |  |         function toggleChildren(btn) { | 
					
						
							|  |  |  |             const row = btn.closest('tr'); | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             const parentCode = row.dataset.code; | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             let nextRow = row.nextElementSibling; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const isExpanded = btn.textContent === '▼'; | 
					
						
							|  |  |  |             btn.textContent = isExpanded ? '▶' : '▼'; | 
					
						
							|  |  |  |             btn.classList.toggle('collapsed', isExpanded); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             // 找到这个权限的所有直接和间接子权限 | 
					
						
							|  |  |  |             const childCodes = getChildPermissionCodes(parentCode); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             // 切换相关子行的显示状态 | 
					
						
							|  |  |  |             while (nextRow) { | 
					
						
							|  |  |  |                 const nextRowCode = nextRow.dataset.code; | 
					
						
							|  |  |  |                 const nextRowParent = permissions.find(p => p.code === nextRowCode)?.parentCode; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 // 如果当前行是目标权限的子权限(直接或间接) | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |                 if (childCodes.includes(nextRowCode)) { | 
					
						
							|  |  |  |                     nextRow.style.display = isExpanded ? 'none' : 'table-row'; | 
					
						
							|  |  |  |                 } else if (!isChildOfAny(nextRowCode, childCodes)) { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                     // 如果不是子权限,说明已到达同级或上级权限,停止处理 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 nextRow = nextRow.nextElementSibling; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // 获取某个权限的所有子权限编码(递归) | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |         function getChildPermissionCodes(parentCode) { | 
					
						
							|  |  |  |             const children = []; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             function findChildren(code) { | 
					
						
							|  |  |  |                 permissions.forEach(p => { | 
					
						
							|  |  |  |                     if (p.parentCode === code) { | 
					
						
							|  |  |  |                         children.push(p.code); | 
					
						
							|  |  |  |                         findChildren(p.code); // 递归查找子权限 | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |             findChildren(parentCode); | 
					
						
							|  |  |  |             return children; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |         // 检查某个权限是否为指定权限列表中任一权限的子权限 | 
					
						
							|  |  |  |         function isChildOfAny(code, parentCodes) { | 
					
						
							|  |  |  |             const permission = permissions.find(p => p.code === code); | 
					
						
							|  |  |  |             if (!permission) return false; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return parentCodes.includes(permission.parentCode) || | 
					
						
							| 
									
										
										
										
											2025-09-05 09:01:44 +00:00
										 |  |  |                    (permission.parentCode && isChildOfAny(permission.parentCode, parentCodes)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // 显示右键菜单 | 
					
						
							|  |  |  |         function showContextMenu(event, row) { | 
					
						
							|  |  |  |             event.preventDefault(); | 
					
						
							|  |  |  |             contextMenuTargetRow = row; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const menu = document.getElementById('contextMenu'); | 
					
						
							|  |  |  |             menu.style.display = 'block'; | 
					
						
							|  |  |  |             menu.style.left = event.pageX + 'px'; | 
					
						
							|  |  |  |             menu.style.top = event.pageY + 'px'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 隐藏右键菜单 | 
					
						
							|  |  |  |         function hideContextMenu() { | 
					
						
							|  |  |  |             document.getElementById('contextMenu').style.display = 'none'; | 
					
						
							|  |  |  |             contextMenuTargetRow = null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 点击其他地方隐藏右键菜单 | 
					
						
							|  |  |  |         document.addEventListener('click', hideContextMenu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 打开新增弹窗 | 
					
						
							|  |  |  |         function openAddModal() { | 
					
						
							|  |  |  |             currentEditingId = null; | 
					
						
							|  |  |  |             document.getElementById('modalTitle').textContent = '新增权限'; | 
					
						
							|  |  |  |             document.getElementById('permissionForm').reset(); | 
					
						
							|  |  |  |             updateParentCodeOptions(); | 
					
						
							|  |  |  |             document.getElementById('permissionModal').classList.add('show'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 添加子权限 | 
					
						
							|  |  |  |         function addChildPermission() { | 
					
						
							|  |  |  |             if (!contextMenuTargetRow) return; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const parentCode = contextMenuTargetRow.dataset.code; | 
					
						
							|  |  |  |             openAddModal(); | 
					
						
							|  |  |  |             document.getElementById('parentCode').value = parentCode; | 
					
						
							|  |  |  |             hideContextMenu(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 编辑权限 | 
					
						
							|  |  |  |         function editPermission() { | 
					
						
							|  |  |  |             if (!contextMenuTargetRow) return; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const id = parseInt(contextMenuTargetRow.dataset.id); | 
					
						
							|  |  |  |             editPermissionById(id); | 
					
						
							|  |  |  |             hideContextMenu(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 根据ID编辑权限 | 
					
						
							|  |  |  |         function editPermissionById(id) { | 
					
						
							|  |  |  |             const permission = permissions.find(p => p.id === id); | 
					
						
							|  |  |  |             if (!permission) return; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             currentEditingId = id; | 
					
						
							|  |  |  |             document.getElementById('modalTitle').textContent = '编辑权限'; | 
					
						
							|  |  |  |             document.getElementById('permissionCode').value = permission.code; | 
					
						
							|  |  |  |             document.getElementById('permissionName').value = permission.name; | 
					
						
							|  |  |  |             document.getElementById('permissionDesc').value = permission.description || ''; | 
					
						
							|  |  |  |             document.getElementById('permissionType').value = permission.type; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |             // 设置可见身份选项 | 
					
						
							|  |  |  |             const visibleRolesSelect = document.getElementById('visibleRoles'); | 
					
						
							|  |  |  |             Array.from(visibleRolesSelect.options).forEach(option => { | 
					
						
							|  |  |  |                 option.selected = permission.visibleRoles && permission.visibleRoles.includes(option.value); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             updateParentCodeOptions(permission.code); | 
					
						
							|  |  |  |             document.getElementById('parentCode').value = permission.parentCode || ''; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             document.getElementById('permissionModal').classList.add('show'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 删除权限 | 
					
						
							|  |  |  |         function deletePermission() { | 
					
						
							|  |  |  |             if (!contextMenuTargetRow) return; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const id = parseInt(contextMenuTargetRow.dataset.id); | 
					
						
							|  |  |  |             deletePermissionById(id); | 
					
						
							|  |  |  |             hideContextMenu(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 根据ID删除权限 | 
					
						
							|  |  |  |         function deletePermissionById(id) { | 
					
						
							|  |  |  |             const permission = permissions.find(p => p.id === id); | 
					
						
							|  |  |  |             if (!permission) return; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             // 检查是否有子权限 | 
					
						
							|  |  |  |             const hasChildren = permissions.some(p => p.parentCode === permission.code); | 
					
						
							|  |  |  |             if (hasChildren) { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 alert('该权限下有子权限,请先删除子权限!'); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (confirm(`确定要删除权限"${permission.name}"吗?`)) { | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 permissions = permissions.filter(p => p.id !== id); | 
					
						
							|  |  |  |                 renderPermissionsTable(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 更新父级权限选项 | 
					
						
							|  |  |  |         function updateParentCodeOptions(excludeCode = '') { | 
					
						
							|  |  |  |             const select = document.getElementById('parentCode'); | 
					
						
							|  |  |  |             select.innerHTML = '<option value="">无父级权限</option>'; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             permissions.forEach(permission => { | 
					
						
							|  |  |  |                 if (permission.code !== excludeCode && permission.type === 'menu') { | 
					
						
							|  |  |  |                     const option = document.createElement('option'); | 
					
						
							|  |  |  |                     option.value = permission.code; | 
					
						
							|  |  |  |                     option.textContent = `${permission.code} (${permission.name})`; | 
					
						
							|  |  |  |                     select.appendChild(option); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 保存权限 | 
					
						
							|  |  |  |         function savePermission() { | 
					
						
							|  |  |  |             const form = document.getElementById('permissionForm'); | 
					
						
							|  |  |  |             const formData = new FormData(form); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const code = formData.get('code').trim(); | 
					
						
							|  |  |  |             const name = formData.get('name').trim(); | 
					
						
							|  |  |  |             const description = formData.get('description').trim(); | 
					
						
							|  |  |  |             const parentCode = formData.get('parentCode'); | 
					
						
							|  |  |  |             const type = formData.get('type'); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |             // 获取可见身份选项 | 
					
						
							|  |  |  |             const visibleRolesSelect = document.getElementById('visibleRoles'); | 
					
						
							|  |  |  |             const selectedRoles = Array.from(visibleRolesSelect.selectedOptions).map(option => option.value); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             // 验证 | 
					
						
							|  |  |  |             if (!code || !name || !type) { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 alert('请填写必填项!'); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // 检查权限编码是否重复(编辑时排除自身) | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const existingPermission = permissions.find(p => p.code === code && p.id !== currentEditingId); | 
					
						
							|  |  |  |             if (existingPermission) { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                 alert('权限编码已存在!'); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             // 验证父级权限 | 
					
						
							|  |  |  |             if (parentCode) { | 
					
						
							|  |  |  |                 const parentPermission = permissions.find(p => p.code === parentCode); | 
					
						
							|  |  |  |                 if (!parentPermission) { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                     alert('父级权限不存在!'); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (parentPermission.type !== 'menu') { | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  |                     alert('只能选择菜单类型的权限作为父级权限!'); | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             const permissionData = { | 
					
						
							|  |  |  |                 code, | 
					
						
							|  |  |  |                 name, | 
					
						
							|  |  |  |                 description, | 
					
						
							|  |  |  |                 parentCode: parentCode || '', | 
					
						
							| 
									
										
										
										
											2025-09-08 07:56:51 +00:00
										 |  |  |                 type, | 
					
						
							|  |  |  |                 visibleRoles: selectedRoles | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             }; | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             if (currentEditingId) { | 
					
						
							|  |  |  |                 // 编辑权限 | 
					
						
							|  |  |  |                 const index = permissions.findIndex(p => p.id === currentEditingId); | 
					
						
							|  |  |  |                 if (index !== -1) { | 
					
						
							|  |  |  |                     permissions[index] = { ...permissions[index], ...permissionData }; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 // 新增权限 | 
					
						
							|  |  |  |                 const newId = Math.max(...permissions.map(p => p.id), 0) + 1; | 
					
						
							|  |  |  |                 permissions.push({ id: newId, ...permissionData }); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             closeModal(); | 
					
						
							|  |  |  |             renderPermissionsTable(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 关闭弹窗 | 
					
						
							|  |  |  |         function closeModal() { | 
					
						
							|  |  |  |             document.getElementById('permissionModal').classList.remove('show'); | 
					
						
							|  |  |  |             currentEditingId = null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 搜索权限 | 
					
						
							|  |  |  |         function searchPermissions() { | 
					
						
							|  |  |  |             const keyword = document.getElementById('searchInput').value.trim().toLowerCase(); | 
					
						
							|  |  |  |             if (!keyword) { | 
					
						
							|  |  |  |                 renderPermissionsTable(); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             const filteredPermissions = permissions.filter(permission => | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |                 permission.code.toLowerCase().includes(keyword) || | 
					
						
							|  |  |  |                 permission.name.toLowerCase().includes(keyword) || | 
					
						
							|  |  |  |                 (permission.description && permission.description.toLowerCase().includes(keyword)) | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 03:40:01 +00:00
										 |  |  |             renderPermissionsTable(filteredPermissions); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 重置搜索 | 
					
						
							|  |  |  |         function resetSearch() { | 
					
						
							|  |  |  |             document.getElementById('searchInput').value = ''; | 
					
						
							|  |  |  |             renderPermissionsTable(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 监听回车键搜索 | 
					
						
							|  |  |  |         document.getElementById('searchInput').addEventListener('keypress', function(e) { | 
					
						
							|  |  |  |             if (e.key === 'Enter') { | 
					
						
							|  |  |  |                 searchPermissions(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 监听ESC键关闭弹窗 | 
					
						
							|  |  |  |         document.addEventListener('keydown', function(e) { | 
					
						
							|  |  |  |             if (e.key === 'Escape') { | 
					
						
							|  |  |  |                 closeModal(); | 
					
						
							|  |  |  |                 hideContextMenu(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 阻止弹窗背景点击关闭 | 
					
						
							|  |  |  |         document.getElementById('permissionModal').addEventListener('click', function(e) { | 
					
						
							|  |  |  |             if (e.target === this) { | 
					
						
							|  |  |  |                 closeModal(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 初始化页面 | 
					
						
							|  |  |  |         document.addEventListener('DOMContentLoaded', function() { | 
					
						
							|  |  |  |             initSampleData(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     </script> | 
					
						
							|  |  |  | </body> | 
					
						
							| 
									
										
										
										
											2025-10-20 17:40:00 +00:00
										 |  |  | </html> |