diff --git a/dist/css/app.6baf1172.css b/dist/css/app.fc3e06db.css similarity index 87% rename from dist/css/app.6baf1172.css rename to dist/css/app.fc3e06db.css index 53394d9..4862e9a 100644 --- a/dist/css/app.6baf1172.css +++ b/dist/css/app.fc3e06db.css @@ -1 +1 @@ -.navbar[data-v-2d6400c2]{position:sticky;top:0;z-index:1000;width:100%;background:linear-gradient(90deg,#fff,#f8f9fa);box-shadow:0 2px 10px rgba(0,0,0,.05);height:64px}.navbar-container[data-v-2d6400c2]{max-width:1200px;margin:0 auto;padding:0 20px;height:100%;display:flex;align-items:center;justify-content:space-between}.navbar-brand[data-v-2d6400c2]{display:flex;align-items:center;cursor:pointer;transition:opacity .3s}.navbar-brand[data-v-2d6400c2]:hover{opacity:.8}.logo[data-v-2d6400c2]{height:40px;margin-right:12px}.brand-text[data-v-2d6400c2]{font-size:1.5rem;font-weight:700;color:#333;letter-spacing:.5px}.version-badge[data-v-2d6400c2]{background:linear-gradient(135deg,#225fc9,#5390e6);color:#fff;font-size:.75rem;padding:2px 8px;border-radius:12px;margin-left:10px;font-weight:700;box-shadow:0 2px 4px rgba(0,0,0,.2);position:relative;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;height:20px}.version-badge[data-v-2d6400c2]:after{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.4),transparent);transform:skewX(-20deg);animation:shine-2d6400c2 2s infinite}@keyframes shine-2d6400c2{0%{left:-100%}20%{left:200%}to{left:200%}}.navbar-menu[data-v-2d6400c2]{display:flex;gap:30px;align-items:center}.nav-item[data-v-2d6400c2]{text-decoration:none;color:#555;font-weight:500;font-size:16px;padding:8px 0;position:relative;transition:color .3s}.nav-item[data-v-2d6400c2]:hover{color:#409eff}.nav-item.active[data-v-2d6400c2]{color:#409eff;font-weight:600}.nav-item.active[data-v-2d6400c2]:after{content:"";position:absolute;bottom:0;left:0;width:100%;height:2px;background-color:#409eff;border-radius:2px}.navbar-toggle[data-v-2d6400c2]{background:none;border:none;cursor:pointer;padding:10px;display:none;margin-right:-10px}.hamburger-box[data-v-2d6400c2]{width:24px;height:24px;display:flex;align-items:center;justify-content:center;position:relative}.hamburger-inner[data-v-2d6400c2],.hamburger-inner[data-v-2d6400c2]:after,.hamburger-inner[data-v-2d6400c2]:before{width:24px;height:2px;background-color:#333;border-radius:2px;position:absolute;transition:transform .3s cubic-bezier(.4,.01,.165,.99),opacity .3s cubic-bezier(.4,.01,.165,.99),top .3s cubic-bezier(.4,.01,.165,.99),bottom .3s cubic-bezier(.4,.01,.165,.99);left:0}.hamburger-inner[data-v-2d6400c2]{top:50%;transform:translateY(-50%)}.hamburger-inner[data-v-2d6400c2]:before{content:"";top:-8px}.hamburger-inner[data-v-2d6400c2]:after{content:"";bottom:-8px}.hamburger-inner.is-active[data-v-2d6400c2]{transform:rotate(45deg)}.hamburger-inner.is-active[data-v-2d6400c2]:before{top:0;opacity:0}.hamburger-inner.is-active[data-v-2d6400c2]:after{bottom:0;transform:rotate(-90deg)}.mobile-menu-overlay[data-v-2d6400c2]{position:fixed;top:64px;left:0;width:100%;height:calc(100vh - 64px);background-color:rgba(0,0,0,.5);z-index:998}.mobile-menu-content[data-v-2d6400c2]{position:fixed;top:64px;left:0;right:0;background-color:#fff;z-index:999;box-shadow:0 4px 12px rgba(0,0,0,.1);padding:20px;display:flex;flex-direction:column;box-sizing:border-box}.mobile-menu-header[data-v-2d6400c2]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;border-bottom:1px solid #eee;padding-bottom:10px}.mobile-menu-title[data-v-2d6400c2]{font-size:1.2rem;font-weight:700;color:#333}.close-btn[data-v-2d6400c2]{font-size:2rem;line-height:1;cursor:pointer;color:#999}.mobile-links[data-v-2d6400c2]{display:flex;flex-direction:column;gap:15px}.mobile-nav-item[data-v-2d6400c2]{text-decoration:none;color:#333;font-size:1.1rem;padding:10px;border-radius:8px;background-color:#f9f9f9;text-align:center;transition:background-color .2s}.mobile-nav-item.active[data-v-2d6400c2]{background-color:#ecf5ff;color:#409eff;font-weight:600}.mobile-footer[data-v-2d6400c2]{margin-top:30px;text-align:center;color:#999;font-size:.8rem}@media (max-width:768px){.desktop-only[data-v-2d6400c2]{display:none}.mobile-only[data-v-2d6400c2]{display:block}.navbar-container[data-v-2d6400c2]{padding:0 15px}}.fade-enter-active[data-v-2d6400c2],.fade-leave-active[data-v-2d6400c2]{transition:opacity .3s}.fade-enter-from[data-v-2d6400c2],.fade-leave-to[data-v-2d6400c2]{opacity:0}.slide-down-enter-active[data-v-2d6400c2],.slide-down-leave-active[data-v-2d6400c2]{transition:transform .3s ease,opacity .3s}.slide-down-enter-from[data-v-2d6400c2],.slide-down-leave-to[data-v-2d6400c2]{transform:translateY(-20px);opacity:0}body,html{height:100%;margin:0;padding:0;background-color:#f5f7fa;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.app-layout{min-height:100vh;display:flex;flex-direction:column}.main-content{flex:1;padding:20px;width:100%;max-width:1200px;margin:0 auto;box-sizing:border-box}.forbidden-container{text-align:center;padding:50px 20px;display:flex;align-items:center;flex-direction:column;justify-content:center;min-height:100vh}.forbidden-title{color:#d9534f;font-size:2.5rem;margin-bottom:20px}.forbidden-text{font-size:1.25rem;color:#333;margin-bottom:30px;max-width:600px}.forbidden-back-btn{background-color:#5cb85c;color:#fff;padding:10px 20px;font-size:1.1rem;border:none;border-radius:5px;cursor:pointer;transition:background-color .3s ease}.forbidden-back-btn:hover{background-color:#4cae4c}@media (max-width:768px){.main-content{padding:15px}.forbidden-title{font-size:1.8rem}.forbidden-text{font-size:1rem}}h2[data-v-b5d4cca8]{color:#333;margin-bottom:10px;font-size:42px}@media (max-width:768px){h2[data-v-b5d4cca8]{font-size:28px}}p[data-v-b5d4cca8]{line-height:1.6;margin-bottom:15px;color:#666}.guide-link[data-v-b5d4cca8]{color:#0056b3;text-decoration:underline;cursor:pointer}.guide-link[data-v-b5d4cca8]:hover{color:#003d82}.course-list-page[data-v-2964ca48]{max-width:1200px;margin:0 auto;padding:20px;min-height:100vh;background-color:#f8f9fa}.page-title[data-v-2964ca48]{margin-bottom:20px;font-size:24px;color:#333;font-weight:700}.empty-message[data-v-2964ca48],.loading-message[data-v-2964ca48]{font-size:16px;color:#666;text-align:center;margin-top:40px}.course-cards[data-v-2964ca48]{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-bottom:40px}.course-card[data-v-2964ca48]{background:#fff;border-radius:12px;border:1px solid #f0f0f0;overflow:hidden;cursor:pointer;transition:all .3s ease;display:flex;flex-direction:column;height:100%;position:relative}.course-card[data-v-2964ca48]:hover{transform:translateY(-5px);box-shadow:0 8px 24px rgba(0,0,0,.08);border-color:#e0e0e0}.card-header[data-v-2964ca48]{padding:16px;border-bottom:1px solid #f9f9f9;display:flex;justify-content:space-between;align-items:flex-start;gap:10px}.course-name-title[data-v-2964ca48]{font-size:16px;font-weight:600;color:#333;margin:0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;flex:1}.status-tag[data-v-2964ca48]{font-size:12px;padding:2px 8px;border-radius:10px;white-space:nowrap;background:#eee;color:#666}.status-approved[data-v-2964ca48]{background:#e6f7ff;color:#1890ff;border:1px solid #91d5ff}.status-pending[data-v-2964ca48]{background:#fffbe6;color:#faad14;border:1px solid #ffe58f}.status-rejected[data-v-2964ca48]{background:#fff1f0;color:#f5222d;border:1px solid #ffa39e}.card-body[data-v-2964ca48]{padding:16px;flex:1}.info-row[data-v-2964ca48]{display:flex;justify-content:space-between;margin-bottom:8px;font-size:13px;color:#666}.info-label[data-v-2964ca48]{color:#999;margin-right:8px;flex-shrink:0}.info-val[data-v-2964ca48]{text-align:right;color:#333;font-weight:500}.truncate[data-v-2964ca48]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%}.card-footer[data-v-2964ca48]{padding:12px 16px;background:#fafafa;border-top:1px solid #f0f0f0}.time-info[data-v-2964ca48]{display:flex;flex-direction:column;gap:4px}.time-row[data-v-2964ca48]{display:flex;justify-content:space-between;font-size:12px;color:#999}.pagination-bar[data-v-2964ca48]{display:flex;justify-content:center;gap:8px;margin-bottom:40px;flex-wrap:wrap}.pagination-bar button[data-v-2964ca48]{min-width:36px;height:36px;padding:0 10px;border:1px solid #e0e0e0;background:#fff;color:#606266;border-radius:6px;cursor:pointer;transition:all .2s;font-size:14px}.pagination-bar button[data-v-2964ca48]:hover:not(:disabled){color:#409eff;border-color:#409eff}.pagination-bar button.active[data-v-2964ca48]{background-color:#409eff;border-color:#409eff;color:#fff}.pagination-bar button[data-v-2964ca48]:disabled{background:#f5f7fa;color:#c0c4cc;cursor:not-allowed}.add-course-section[data-v-2964ca48]{background:#fff;border-radius:12px;padding:24px;box-shadow:0 2px 12px rgba(0,0,0,.05);margin-top:40px}.section-header[data-v-2964ca48]{display:flex;align-items:center;gap:15px;margin-bottom:20px}.section-header h2[data-v-2964ca48]{margin:0;font-size:20px;color:#333}.help-btn[data-v-2964ca48]{display:flex;align-items:center;gap:5px;padding:5px 10px;background:#f8f9fa;border:1px solid #dee2e6;border-radius:4px;cursor:pointer;font-size:14px;color:#495057;transition:all .2s ease}.help-btn[data-v-2964ca48]:hover{background:#e9ecef}.help-icon[data-v-2964ca48]{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background:#6c757d;color:#fff;font-size:12px;font-weight:700}.input-grid[data-v-2964ca48]{display:grid;grid-template-columns:repeat(2,1fr);gap:30px}.input-group[data-v-2964ca48]{display:flex;flex-direction:column;gap:8px}.input-group label[data-v-2964ca48]{font-size:14px;color:#606266;font-weight:500}.modern-input[data-v-2964ca48],.modern-select[data-v-2964ca48]{width:100%;box-sizing:border-box;padding:10px;border:1px solid #e0e0e0;border-radius:8px;font-size:14px;transition:all .3s;background:#fff}.modern-input[data-v-2964ca48]:focus,.modern-select[data-v-2964ca48]:focus{border-color:#409eff;box-shadow:0 0 0 2px rgba(64,158,255,.2);outline:none}.button-group[data-v-2964ca48]{grid-column:1/-1;display:flex;justify-content:flex-end;margin-top:10px}.submit-btn[data-v-2964ca48]{padding:10px 30px;background-color:#409eff;color:#fff;border:none;border-radius:8px;font-weight:500;cursor:pointer;transition:all .3s}.submit-btn[data-v-2964ca48]:hover{background-color:#66b1ff;transform:translateY(-1px)}.help-modal[data-v-2964ca48]{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center;z-index:1000}.help-modal-content[data-v-2964ca48]{background:#fff;border-radius:12px;width:90%;max-width:600px;max-height:80vh;overflow-y:auto;padding:20px;box-shadow:0 4px 6px rgba(0,0,0,.1)}.help-modal-header[data-v-2964ca48]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #dee2e6}.close-btn[data-v-2964ca48]{background:none;border:none;font-size:24px;cursor:pointer;color:#6c757d}.help-section[data-v-2964ca48]{margin-bottom:20px}.help-modal-header h3[data-v-2964ca48]{font-size:20px;font-weight:700;margin:0}.help-section h4[data-v-2964ca48]{color:#0056b3;margin-bottom:10px}.help-section p[data-v-2964ca48]{color:#495057;line-height:1.6;margin-bottom:8px}@media (max-width:768px){.course-cards[data-v-2964ca48]{grid-template-columns:repeat(2,1fr);gap:12px}.input-grid[data-v-2964ca48]{grid-template-columns:1fr}.course-name-title[data-v-2964ca48]{font-size:14px}.status-tag[data-v-2964ca48]{font-size:10px;padding:1px 5px}}@media (max-width:480px){.course-cards[data-v-2964ca48]{grid-template-columns:1fr}}.rating-page[data-v-7d8ad36d]{max-width:1200px;margin:0 auto;padding:20px;background-color:#f8f9fa;min-height:100vh}.rating-note[data-v-7d8ad36d]{font-size:14px;color:#666;margin-bottom:20px;text-align:center}.search-sort-bar[data-v-7d8ad36d]{background:#fff;border-radius:12px;padding:20px;margin-bottom:30px;box-shadow:0 2px 12px rgba(0,0,0,.05);display:flex;flex-direction:column;gap:20px}.search-inputs[data-v-7d8ad36d]{display:flex;gap:15px}.input-wrapper[data-v-7d8ad36d]{position:relative;flex:1;display:flex;align-items:center}.search-icon[data-v-7d8ad36d]{position:absolute;left:12px;color:#999;font-size:16px}.modern-input[data-v-7d8ad36d]{width:100%;padding:10px 10px 10px 36px;border:1px solid #e0e0e0;border-radius:8px;font-size:14px;transition:all .3s}.modern-input[data-v-7d8ad36d]:focus{border-color:#409eff;box-shadow:0 0 0 2px rgba(64,158,255,.2);outline:none}.teacher-input[data-v-7d8ad36d]{flex:1.5}.filters-row[data-v-7d8ad36d]{border-top:1px solid #f0f0f0;padding-top:15px}.category-checkboxes[data-v-7d8ad36d]{display:flex;flex-wrap:wrap;gap:15px}.checkbox-label[data-v-7d8ad36d]{display:flex;align-items:center;cursor:pointer;font-size:14px;color:#555;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:6px 12px;background:#f5f7fa;border-radius:20px;transition:all .2s}.checkbox-label[data-v-7d8ad36d]:hover{background:#e6e8eb}.checkbox-label input[data-v-7d8ad36d]{margin-right:6px}.actions-row[data-v-7d8ad36d]{display:flex;justify-content:space-between;align-items:center;border-top:1px solid #f0f0f0;padding-top:15px}.select-group[data-v-7d8ad36d]{display:flex;gap:15px}.modern-select[data-v-7d8ad36d]{padding:8px 12px;border:1px solid #e0e0e0;border-radius:6px;font-size:14px;color:#555;background:#fff;cursor:pointer}.search-btn[data-v-7d8ad36d]{padding:8px 24px;background-color:#409eff;color:#fff;border:none;border-radius:6px;font-weight:500;cursor:pointer;transition:all .3s}.search-btn[data-v-7d8ad36d]:hover{background-color:#66b1ff;transform:translateY(-1px)}.course-cards[data-v-7d8ad36d]{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-bottom:30px}.course-card[data-v-7d8ad36d]{background:#fff;border-radius:12px;border:1px solid #f0f0f0;overflow:hidden;cursor:pointer;transition:all .3s ease;display:flex;flex-direction:column;position:relative;height:100%}.course-card[data-v-7d8ad36d]:hover{transform:translateY(-5px);box-shadow:0 8px 24px rgba(0,0,0,.08);border-color:#e0e0e0}.card-header[data-v-7d8ad36d]{padding:16px;border-bottom:1px solid #f9f9f9}.course-name-title[data-v-7d8ad36d]{font-size:16px;font-weight:600;color:#333;margin:0 0 8px 0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;height:44px}.course-tags[data-v-7d8ad36d]{display:flex;flex-wrap:wrap;gap:6px}.mini-tag[data-v-7d8ad36d]{font-size:10px;padding:2px 6px;border:1px solid;border-radius:4px;white-space:nowrap}.card-body[data-v-7d8ad36d]{padding:16px;flex:1}.info-row[data-v-7d8ad36d]{display:flex;justify-content:space-between;margin-bottom:8px;font-size:13px;color:#666}.info-label[data-v-7d8ad36d]{color:#999;margin-right:8px;flex-shrink:0}.info-val[data-v-7d8ad36d]{text-align:right;color:#333;font-weight:500}.truncate[data-v-7d8ad36d]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%}.card-footer[data-v-7d8ad36d]{padding:12px 16px;background:#fafafa;border-top:1px solid #f0f0f0}.rating-info[data-v-7d8ad36d]{display:flex;align-items:baseline;margin-bottom:8px}.score[data-v-7d8ad36d]{font-size:24px;font-weight:700;color:#f90;line-height:1}.score-label[data-v-7d8ad36d]{font-size:12px;color:#f90;margin-left:2px}.count[data-v-7d8ad36d]{font-size:12px;color:#999;margin-left:auto}.top-comment[data-v-7d8ad36d]{font-size:12px;color:#666;background:#fff;padding:8px;border-radius:6px;font-style:italic;line-height:1.4;border:1px solid #eee;height:50px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.top-comment.placeholder[data-v-7d8ad36d]{color:#ccc;font-style:normal;display:flex;align-items:center;justify-content:center}.pagination-bar[data-v-7d8ad36d]{display:flex;justify-content:center;gap:8px;margin-top:30px}.pagination-bar button[data-v-7d8ad36d]{min-width:36px;height:36px;padding:0 10px;border:1px solid #e0e0e0;background:#fff;color:#606266;border-radius:6px;cursor:pointer;transition:all .2s;font-size:14px}.pagination-bar button[data-v-7d8ad36d]:hover:not(:disabled){color:#409eff;border-color:#409eff}.pagination-bar button.active[data-v-7d8ad36d]{background-color:#409eff;border-color:#409eff;color:#fff}.pagination-bar button[data-v-7d8ad36d]:disabled{background:#f5f7fa;color:#c0c4cc;cursor:not-allowed}@media (max-width:768px){.course-cards[data-v-7d8ad36d]{grid-template-columns:repeat(2,1fr);gap:12px}.search-sort-bar[data-v-7d8ad36d]{padding:15px}.search-inputs[data-v-7d8ad36d]{flex-direction:column}.actions-row[data-v-7d8ad36d]{flex-direction:column;gap:15px}.select-group[data-v-7d8ad36d]{width:100%;flex-direction:column;gap:10px}.modern-select[data-v-7d8ad36d]{width:100%}.pagination-bar[data-v-7d8ad36d]{flex-wrap:wrap}.search-btn[data-v-7d8ad36d]{width:100%}.course-name-title[data-v-7d8ad36d]{font-size:14px;height:40px}.info-row[data-v-7d8ad36d]{font-size:12px}.score[data-v-7d8ad36d]{font-size:20px}}.rating-page[data-v-3228e625]{max-width:1200px;margin:0 auto;padding:20px;background-color:#f8f9fa;min-height:100vh}.rating-note[data-v-3228e625]{font-size:14px;color:#666;margin-bottom:20px;text-align:center}.search-sort-bar[data-v-3228e625]{background:#fff;border-radius:12px;padding:20px;margin-bottom:30px;box-shadow:0 2px 12px rgba(0,0,0,.05);display:flex;flex-direction:column;gap:20px}.search-inputs[data-v-3228e625]{display:flex;gap:15px}.input-wrapper[data-v-3228e625]{position:relative;flex:1;display:flex;align-items:center}.search-icon[data-v-3228e625]{position:absolute;left:12px;color:#999;font-size:16px}.modern-input[data-v-3228e625]{width:100%;padding:10px 10px 10px 36px;border:1px solid #e0e0e0;border-radius:8px;font-size:14px;transition:all .3s}.modern-input[data-v-3228e625]:focus{border-color:#409eff;box-shadow:0 0 0 2px rgba(64,158,255,.2);outline:none}.teacher-input[data-v-3228e625]{flex:1.5}.filters-row[data-v-3228e625]{border-top:1px solid #f0f0f0;padding-top:15px}.category-checkboxes[data-v-3228e625]{display:flex;flex-wrap:wrap;gap:15px}.checkbox-label[data-v-3228e625]{display:flex;align-items:center;cursor:pointer;font-size:14px;color:#555;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:6px 12px;background:#f5f7fa;border-radius:20px;transition:all .2s}.checkbox-label[data-v-3228e625]:hover{background:#e6e8eb}.checkbox-label input[data-v-3228e625]{margin-right:6px}.actions-row[data-v-3228e625]{display:flex;justify-content:space-between;align-items:center;border-top:1px solid #f0f0f0;padding-top:15px}.select-group[data-v-3228e625]{display:flex;gap:15px}.modern-select[data-v-3228e625]{padding:8px 12px;border:1px solid #e0e0e0;border-radius:6px;font-size:14px;color:#555;background:#fff;cursor:pointer}.search-btn[data-v-3228e625]{padding:8px 24px;background-color:#409eff;color:#fff;border:none;border-radius:6px;font-weight:500;cursor:pointer;transition:all .3s}.search-btn[data-v-3228e625]:hover{background-color:#66b1ff;transform:translateY(-1px)}.course-cards[data-v-3228e625]{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-bottom:30px}.course-card[data-v-3228e625]{background:#fff;border-radius:12px;border:1px solid #f0f0f0;overflow:hidden;cursor:pointer;transition:all .3s ease;display:flex;flex-direction:column;position:relative;height:100%}.course-card[data-v-3228e625]:hover{transform:translateY(-5px);box-shadow:0 8px 24px rgba(0,0,0,.08);border-color:#e0e0e0}.card-header[data-v-3228e625]{padding:16px;border-bottom:1px solid #f9f9f9}.course-name-title[data-v-3228e625]{font-size:16px;font-weight:600;color:#333;margin:0 0 8px 0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;height:44px}.course-tags[data-v-3228e625]{display:flex;flex-wrap:wrap;gap:6px}.mini-tag[data-v-3228e625]{font-size:10px;padding:2px 6px;border:1px solid;border-radius:4px;white-space:nowrap}.card-body[data-v-3228e625]{padding:16px;flex:1}.info-row[data-v-3228e625]{display:flex;justify-content:space-between;margin-bottom:8px;font-size:13px;color:#666}.info-label[data-v-3228e625]{color:#999;margin-right:8px;flex-shrink:0}.info-val[data-v-3228e625]{text-align:right;color:#333;font-weight:500}.truncate[data-v-3228e625]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%}.card-footer[data-v-3228e625]{padding:12px 16px;background:#fafafa;border-top:1px solid #f0f0f0}.rating-info[data-v-3228e625]{display:flex;align-items:baseline;margin-bottom:8px}.score[data-v-3228e625]{font-size:24px;font-weight:700;color:#f90;line-height:1}.score-label[data-v-3228e625]{font-size:12px;color:#f90;margin-left:2px}.count[data-v-3228e625]{font-size:12px;color:#999;margin-left:auto}.top-comment[data-v-3228e625]{font-size:12px;color:#666;background:#fff;padding:8px;border-radius:6px;font-style:italic;line-height:1.4;border:1px solid #eee;height:50px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.top-comment.placeholder[data-v-3228e625]{color:#ccc;font-style:normal;display:flex;align-items:center;justify-content:center}.pagination-bar[data-v-3228e625]{display:flex;justify-content:center;gap:8px;margin-top:30px}.pagination-bar button[data-v-3228e625]{min-width:36px;height:36px;padding:0 10px;border:1px solid #e0e0e0;background:#fff;color:#606266;border-radius:6px;cursor:pointer;transition:all .2s;font-size:14px}.pagination-bar button[data-v-3228e625]:hover:not(:disabled){color:#409eff;border-color:#409eff}.pagination-bar button.active[data-v-3228e625]{background-color:#409eff;border-color:#409eff;color:#fff}.pagination-bar button[data-v-3228e625]:disabled{background:#f5f7fa;color:#c0c4cc;cursor:not-allowed}@media (max-width:768px){.course-cards[data-v-3228e625]{grid-template-columns:repeat(2,1fr);gap:12px}.search-sort-bar[data-v-3228e625]{padding:15px}.search-inputs[data-v-3228e625]{flex-direction:column}.actions-row[data-v-3228e625]{flex-direction:column;gap:15px}.select-group[data-v-3228e625]{width:100%;flex-direction:column;gap:10px}.modern-select[data-v-3228e625]{width:100%}.pagination-bar[data-v-3228e625]{flex-wrap:wrap}.search-btn[data-v-3228e625]{width:100%}.course-name-title[data-v-3228e625]{font-size:14px;height:40px}.info-row[data-v-3228e625]{font-size:12px}.score[data-v-3228e625]{font-size:20px}}.modal-overlay[data-v-9c153036]{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center;z-index:999}.loading[data-v-9c153036]{display:flex;align-items:center;justify-content:center;flex-direction:column;text-align:center;height:200px}.el-icon[data-v-9c153036]{font-size:40px;margin-bottom:10px}.modal-content[data-v-9c153036]{background-color:#fff;padding:20px;border-radius:8px;width:80%;height:80%;display:flex;flex-direction:row;justify-content:space-between;position:relative}.close[data-v-9c153036]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.course-detail[data-v-9c153036]{max-height:calc(90vh - 120px);overflow-y:auto;overflow-x:auto;padding-right:15px;width:40%}.course-detail[data-v-9c153036]::-webkit-scrollbar{width:6px;height:6px}.course-detail[data-v-9c153036]::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.course-detail[data-v-9c153036]::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.course-detail[data-v-9c153036]::-webkit-scrollbar-thumb:hover{background:#555}.course-detail[data-v-9c153036]>*{min-width:-moz-fit-content;min-width:fit-content}.rating-section[data-v-9c153036]{margin-top:20px}.total-rating[data-v-9c153036]{font-size:40px;margin-bottom:10px}.stars span[data-v-9c153036]{font-size:30px;cursor:pointer;transition:color .3s}.stars .highlighted[data-v-9c153036]{color:gold}.stars span[data-v-9c153036]:not(.highlighted){color:#ccc}.comment-section[data-v-9c153036]{width:55%;padding-left:20px}.comments-list[data-v-9c153036]{max-height:350px;overflow-y:auto;margin-bottom:20px}.comment[data-v-9c153036]{padding:10px 0;border-bottom:1px solid #ddd}.like-section[data-v-9c153036]{cursor:pointer;color:gray}.like-section.liked[data-v-9c153036]{color:red}.new-comment[data-v-9c153036]{display:flex;flex-direction:column}.new-comment input[data-v-9c153036],.new-comment textarea[data-v-9c153036]{margin-bottom:10px;padding:5px;border-radius:5px;border:1px solid #ccc}.new-comment button[data-v-9c153036]{padding:10px;background-color:#007bff;color:#fff;border:none;border-radius:5px;cursor:pointer}.comment-meta[data-v-9c153036],.comment-time[data-v-9c153036]{font-size:13px}.progress[data-v-9c153036]{margin-bottom:5px;width:250px}[data-v-9c153036] .progress .el-progress-bar__outer{height:20px!important;line-height:40px;background-color:#a19999}.course-title[data-v-9c153036]{display:inline-flex;align-items:center;justify-content:center;padding:2px 6px;border:1px solid;border-radius:12px;margin-left:4px;font-size:.85em;min-height:20px}.share-btn[data-v-9c153036]{background-color:#4caf50;color:#fff;border:none;padding:6px 12px;margin-left:10px;border-radius:4px;cursor:pointer;font-size:14px}.share-btn[data-v-9c153036]:hover{background-color:#45a049}.error-modal[data-v-9c153036],.share-modal[data-v-9c153036]{position:fixed;top:20%;left:50%;transform:translateX(-50%);color:#fff;padding:15px;border-radius:10px;text-align:center;box-shadow:0 4px 8px rgba(0,0,0,.1);font-size:16px;z-index:9999;animation:fadeInDown-9c153036 .5s ease}.share-modal[data-v-9c153036]{background-color:#4caf50}.error-modal[data-v-9c153036]{background-color:#f44}@keyframes fadeInDown-9c153036{0%{opacity:0;transform:translate(-50%,-30px)}to{opacity:1;transform:translate(-50%)}}.chat-start-btn[data-v-9c153036]{margin-left:10px;padding:5px 10px;background-color:#409eff;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color .3s ease,transform .2s ease}.chat-start-btn[data-v-9c153036]:hover{background-color:#66b1ff;transform:scale(1.05)}.chat-start-btn[data-v-9c153036]:active{background-color:#3a8ee6;transform:scale(.95)}.chat-modal-overlay[data-v-9c153036]{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;justify-content:center;align-items:center;z-index:1000;animation:chat-fadeIn-9c153036 .3s ease}.chat-modal-content[data-v-9c153036]{background:#fff;padding:20px;border-radius:8px;width:400px;box-shadow:0 2px 10px rgba(0,0,0,.1);text-align:center;animation:chat-slideIn-9c153036 .3s ease;position:relative}.chat-modal-content .chat-close-btn[data-v-9c153036]{position:absolute;top:10px;right:15px;font-size:20px;color:#999;cursor:pointer;transition:color .3s ease}.chat-modal-content .chat-close-btn[data-v-9c153036]:hover{color:#333}.chat-modal-content h3[data-v-9c153036]{margin-top:0;color:#333;font-size:18px}.chat-modal-actions[data-v-9c153036]{margin-top:20px;display:flex;justify-content:space-around}.chat-modal-actions button[data-v-9c153036]{padding:10px 20px;font-size:14px;border:none;border-radius:4px;cursor:pointer;transition:background-color .3s ease,transform .2s ease}.chat-modal-actions button[data-v-9c153036]:first-child{background-color:#409eff;color:#fff}.chat-modal-actions button[data-v-9c153036]:first-child:hover{background-color:#66b1ff}.chat-modal-actions button[data-v-9c153036]:first-child:active{background-color:#3a8ee6}.chat-modal-actions button[data-v-9c153036]:last-child{background-color:#f5f5f5;color:#666}.chat-modal-actions button[data-v-9c153036]:last-child:hover{background-color:#e0e0e0}.chat-modal-actions button[data-v-9c153036]:last-child:active{background-color:#d6d6d6}.chat-textarea[data-v-9c153036]{border:1px solid #dcdfe6;border-radius:4px;padding:10px;font-size:14px;width:100%;height:100px;box-sizing:border-box;resize:none;outline:none;transition:border-color .3s ease}.chat-textarea[data-v-9c153036]:focus{border-color:#409eff}@keyframes chat-fadeIn-9c153036{0%{opacity:0}to{opacity:1}}@keyframes chat-slideIn-9c153036{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}.delete-btn[data-v-9c153036]{color:red;background:none;border:none;cursor:pointer;margin-left:10px;font-size:14px;padding:2px 8px}.delete-btn[data-v-9c153036]:hover{text-decoration:underline}.comment-actions[data-v-9c153036]{display:flex;align-items:center;margin-top:10px;font-size:14px}.ai-summary[data-v-9c153036]{margin-top:15px;padding:10px;background-color:#f5f5f5;border-radius:4px;line-height:1.5}.typing-cursor[data-v-9c153036]{display:inline-block;width:6px;height:14px;background-color:#000;animation:blink-9c153036 1s step-start infinite;margin-left:2px;vertical-align:middle}@keyframes blink-9c153036{50%{opacity:0}}@media (max-width:768px){.modal-content[data-v-9c153036]{width:95%;height:95%;flex-direction:column;overflow-y:auto}.course-detail[data-v-9c153036]{width:100%;height:auto;max-height:none;border-right:none;border-bottom:1px solid #eee;padding-right:0;padding-bottom:20px;margin-bottom:20px}.comment-section[data-v-9c153036]{width:100%;padding-left:0}.total-rating[data-v-9c153036]{font-size:32px}.chat-modal-content[data-v-9c153036]{width:90%}}.chat-page[data-v-38851032]{display:flex;height:98vh;overflow:hidden}.sidebar[data-v-38851032]{width:300px;border-right:1px solid #ddd;display:flex;flex-direction:column;padding:10px;background-color:#f9f9f9}.sidebar h3[data-v-38851032]{margin-bottom:10px}.conversation-item[data-v-38851032]{padding:10px;margin:5px 0;border-radius:5px;cursor:pointer;background-color:#fff;transition:background-color .2s}.conversation-item[data-v-38851032]:hover{background-color:#f0f0f0}.conversation-item.active[data-v-38851032]{background-color:#e6f7ff;border-left:4px solid #1890ff}.conversation-name[data-v-38851032]{font-weight:700;display:flex;align-items:center}.role-label[data-v-38851032]{color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.role-label.owner[data-v-38851032]{background-color:#2196f3}.role-label.member[data-v-38851032]{background-color:#4caf50}.conversation-last-message[data-v-38851032],.conversation-updated-at[data-v-38851032]{color:#999;font-size:12px}.new-message-label[data-v-38851032]{background-color:red;color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.chat-container[data-v-38851032]{flex:1;display:flex;flex-direction:column;background-color:#f5f5f5;width:48.5vw;height:98vh;position:relative}.conversation-info[data-v-38851032]{padding:10px;background-color:#fff;border-bottom:1px solid #ddd;display:flex;justify-content:space-between;align-items:center}.message-list[data-v-38851032]{flex:1;padding:10px;overflow-y:auto}.message[data-v-38851032]{margin:10px 0;display:flex;flex-direction:column}.message.self[data-v-38851032]{align-items:flex-end}.message.other[data-v-38851032]{align-items:flex-start}.message-bubble[data-v-38851032]{max-width:60%;padding:10px;border-radius:8px;background-color:#fff;box-shadow:0 1px 3px rgba(0,0,0,.1);position:relative}.message.self .message-bubble[data-v-38851032]{background-color:#daf1da}.message-info[data-v-38851032]{display:flex;margin-top:5px}.message-info.align-right[data-v-38851032]{justify-content:flex-end}.message-info.align-left[data-v-38851032]{justify-content:flex-start}.message-info small[data-v-38851032]{color:#999;font-size:12px;margin-left:5px}.input-container[data-v-38851032]{padding:10px;border-top:1px solid #ddd;text-align:center}.locked-input[data-v-38851032]{height:60px}.locked-input[data-v-38851032] .el-textarea__inner{resize:none!important}.header[data-v-38851032]{display:flex;justify-content:space-between;align-items:center}.connection-status[data-v-38851032]{display:flex;align-items:center;font-size:14px}.status-indicator[data-v-38851032]{width:8px;height:8px;border-radius:50%;margin-right:5px}.status-indicator.connected[data-v-38851032]{background-color:#02f23e}.status-indicator.disconnected[data-v-38851032]{background-color:#f44336}.status-text[data-v-38851032]{font-size:14px;font-weight:400}.connected .status-text[data-v-38851032]{color:#02f23e}.disconnected .status-text[data-v-38851032]{color:#f44336}.mobile-back-btn[data-v-38851032]{display:none;background:none;border:none;color:#007bff;font-size:16px;cursor:pointer;padding:0 10px 0 0;margin-right:10px}@media (max-width:768px){.chat-page[data-v-38851032]{height:calc(100vh - 64px)}.sidebar[data-v-38851032]{width:100%;border-right:none}.chat-container[data-v-38851032]{width:100%;height:100%;display:none}.chat-page.mobile-chat-active .sidebar[data-v-38851032]{display:none}.chat-page.mobile-chat-active .chat-container[data-v-38851032]{display:flex}.mobile-back-btn[data-v-38851032]{display:inline-block}.message-bubble[data-v-38851032]{max-width:80%}.conversation-info[data-v-38851032]{flex-wrap:wrap;gap:10px}}.about-container[data-v-5c1b02c2]{height:90vh;overflow:hidden;padding:20px}.about-page[data-v-5c1b02c2]{max-width:99%;margin:0 auto;height:100%;overflow-y:auto;padding-right:15px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar{width:6px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar-thumb:hover{background:#555}.project-intro[data-v-5c1b02c2]{margin-bottom:40px}h2[data-v-5c1b02c2]{color:#333;margin-bottom:20px;font-size:24px;border-bottom:2px solid #eee;padding-bottom:10px}.intro-content[data-v-5c1b02c2]{line-height:1.8;color:#666}.intro-content p[data-v-5c1b02c2]{margin-bottom:15px}.version-timeline[data-v-5c1b02c2]{margin-top:40px}.version-item[data-v-5c1b02c2]{background-color:#f8f9fa;padding:15px;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,.05);margin-bottom:10px}.version-item h4[data-v-5c1b02c2]{color:#409eff;margin:0 0 10px 0}.version-item p[data-v-5c1b02c2]{color:#666;margin:0}.version-item ul[data-v-5c1b02c2]{list-style-type:disc;margin:0;padding-left:20px}.version-item li[data-v-5c1b02c2]{margin-bottom:5px}[data-v-5c1b02c2] .el-timeline-item__node{background-color:#409eff}[data-v-5c1b02c2] .el-timeline-item__timestamp{color:#409eff;font-weight:700}@media (max-width:768px){.about-container[data-v-5c1b02c2]{height:auto;overflow:visible;padding:10px}.about-page[data-v-5c1b02c2]{overflow-y:visible;height:auto}}.course-detail-page[data-v-482ee958]{background-color:#f5f7fa;min-height:100vh;padding-bottom:40px}.container[data-v-482ee958]{max-width:1200px;margin:0 auto;padding:20px}.loading-state[data-v-482ee958]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:60vh;color:#666}.spinner[data-v-482ee958]{border:4px solid #f3f3f3;border-top:4px solid #409eff;border-radius:50%;width:40px;height:40px;animation:spin-482ee958 1s linear infinite;margin-bottom:15px}@keyframes spin-482ee958{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.card[data-v-482ee958]{background:#fff;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,.05);padding:24px;margin-bottom:24px;transition:all .3s ease}.card[data-v-482ee958]:hover{box-shadow:0 4px 16px rgba(0,0,0,.08)}.top-section[data-v-482ee958]{display:grid;grid-template-columns:1.2fr .8fr;gap:24px}.card-header[data-v-482ee958]{margin-bottom:20px}.course-name[data-v-482ee958]{font-size:24px;color:#333;margin:0;display:flex;align-items:center;flex-wrap:wrap;gap:10px}.tags[data-v-482ee958]{display:flex;gap:8px}.tag[data-v-482ee958]{font-size:12px;padding:2px 8px;border:1px solid;border-radius:12px;white-space:nowrap}.info-grid[data-v-482ee958]{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:24px}.info-item[data-v-482ee958]{display:flex;flex-direction:column}.info-item.full-width[data-v-482ee958]{grid-column:1/-1}.label[data-v-482ee958]{font-size:13px;color:#909399;margin-bottom:4px}.value[data-v-482ee958]{font-size:16px;color:#303133;font-weight:500}.share-btn[data-v-482ee958]{background-color:#ecf5ff;color:#409eff;border:none;padding:10px 20px;border-radius:20px;cursor:pointer;font-weight:500;display:inline-flex;align-items:center;gap:6px;transition:background .2s}.share-btn[data-v-482ee958]:hover{background-color:#d9ecff}.rating-overview[data-v-482ee958]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.total-score[data-v-482ee958]{display:flex;align-items:baseline;gap:8px}.score[data-v-482ee958]{font-size:48px;font-weight:700;color:#409eff;line-height:1}.count[data-v-482ee958]{color:#909399;font-size:14px}.user-rating-action p[data-v-482ee958]{margin:0 0 5px 0;font-size:13px;color:#606266;text-align:center}.stars[data-v-482ee958]{color:#ddd;font-size:24px;cursor:pointer}.stars.interactive span.active[data-v-482ee958],.stars.interactive span[data-v-482ee958]:hover{color:#f7ba2a}.bar-row[data-v-482ee958]{display:flex;align-items:center;gap:10px;margin-bottom:8px;font-size:13px}.star-label[data-v-482ee958]{width:30px;color:#606266}.el-progress[data-v-482ee958]{flex:1}.percent[data-v-482ee958]{width:35px;text-align:right;color:#909399}.section-header[data-v-482ee958]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;border-bottom:1px solid #ebeef5;padding-bottom:15px}.section-header h2[data-v-482ee958]{font-size:18px;margin:0;display:flex;align-items:center;gap:8px}.beta-badge[data-v-482ee958]{background:#f56c6c;color:#fff;font-size:10px;padding:2px 6px;border-radius:4px;vertical-align:top}.ai-disclaimer[data-v-482ee958]{font-size:12px;color:#909399}.ai-content[data-v-482ee958]{line-height:1.6;color:#303133;min-height:80px}.cursor[data-v-482ee958]{animation:blink-482ee958 1s infinite}@keyframes blink-482ee958{50%{opacity:0}}.sort-tabs[data-v-482ee958]{display:flex;gap:10px;font-size:14px;color:#909399}.sort-tabs span[data-v-482ee958]{cursor:pointer}.sort-tabs span.active[data-v-482ee958]{color:#409eff;font-weight:700}.divider[data-v-482ee958]{color:#ebeef5;cursor:default!important}.post-comment[data-v-482ee958]{background:#f9fafc;padding:20px;border-radius:8px;margin-bottom:30px}.input-group[data-v-482ee958]{display:flex;flex-direction:column;gap:10px;margin-bottom:10px}.nickname-input[data-v-482ee958]{padding:8px 12px;border:1px solid #dcdfe6;border-radius:4px;width:200px}.comment-textarea[data-v-482ee958]{padding:10px 12px;border:1px solid #dcdfe6;border-radius:4px;min-height:80px;resize:vertical}.submit-btn[data-v-482ee958]{background:#409eff;color:#fff;border:none;padding:8px 24px;border-radius:4px;cursor:pointer;align-self:flex-end}.comment-item[data-v-482ee958]{border-bottom:1px solid #ebeef5;padding:20px 0}.comment-item[data-v-482ee958]:last-child{border-bottom:none}.comment-header[data-v-482ee958]{display:flex;justify-content:space-between;margin-bottom:8px}.comment-author[data-v-482ee958]{font-weight:700;color:#303133}.comment-date[data-v-482ee958]{font-size:12px;color:#909399}.comment-body[data-v-482ee958]{font-size:14px;color:#606266;margin-bottom:12px;white-space:pre-wrap}.comment-footer[data-v-482ee958]{display:flex;justify-content:space-between;align-items:center;font-size:13px}.rating-tag span[data-v-482ee958]{color:#f56c6c;font-weight:700}.actions[data-v-482ee958]{display:flex;gap:15px}.like-btn[data-v-482ee958]{cursor:pointer;color:#909399}.like-btn.liked[data-v-482ee958]{color:#f56c6c}.action-link[data-v-482ee958]{background:none;border:none;cursor:pointer;font-size:13px}.action-link.delete[data-v-482ee958]{color:#f56c6c}.action-link.chat[data-v-482ee958]{color:#409eff}.toast[data-v-482ee958]{position:fixed;top:80px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.8);color:#fff;padding:10px 20px;border-radius:4px;z-index:2000}.modal-overlay[data-v-482ee958]{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:2000}.modal-box[data-v-482ee958]{background:#fff;width:90%;max-width:400px;padding:24px;border-radius:8px;position:relative}.close-btn[data-v-482ee958]{position:absolute;right:15px;top:10px;font-size:24px;cursor:pointer;color:#909399}.modal-textarea[data-v-482ee958]{width:90%;min-height:100px;margin:15px 0;padding:10px;border:1px solid #dcdfe6;border-radius:4px;resize:none}.modal-actions[data-v-482ee958]{display:flex;justify-content:flex-end;gap:10px}.primary-btn[data-v-482ee958]{background:#409eff;color:#fff;border:none;padding:8px 20px;border-radius:4px;cursor:pointer}.secondary-btn[data-v-482ee958]{background:#fff;border:1px solid #dcdfe6;padding:8px 20px;border-radius:4px;cursor:pointer}@media (max-width:768px){.top-section[data-v-482ee958]{grid-template-columns:1fr;gap:16px}.info-grid[data-v-482ee958]{grid-template-columns:1fr}.rating-overview[data-v-482ee958]{flex-direction:column;align-items:flex-start;gap:15px}.user-rating-action[data-v-482ee958]{width:100%;display:flex;justify-content:space-between;align-items:center}.score[data-v-482ee958]{font-size:36px}.nickname-input[data-v-482ee958]{width:100%}}.not-found-page[data-v-655c3ea4]{display:flex;justify-content:center;align-items:center;min-height:80vh;text-align:center;background-color:#f5f7fa;padding:20px}.content[data-v-655c3ea4]{background:#fff;padding:40px 60px;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,.1);max-width:500px;width:100%}.error-icon[data-v-655c3ea4]{font-size:64px;margin-bottom:20px}.error-code[data-v-655c3ea4]{font-size:72px;font-weight:700;color:#409eff;margin:0;line-height:1}.error-message[data-v-655c3ea4]{font-size:24px;color:#303133;margin:10px 0 20px;font-weight:500}.description[data-v-655c3ea4]{color:#606266;margin-bottom:30px;font-size:16px}.home-btn[data-v-655c3ea4]{display:inline-block;padding:12px 24px;background-color:#409eff;color:#fff;text-decoration:none;border-radius:6px;transition:background-color .3s;font-weight:500}.home-btn[data-v-655c3ea4]:hover{background-color:#66b1ff}body{font-family:Microsoft YaHei,微软雅黑,Arial,sans-serif;margin:0;padding:0}*{font-family:inherit} \ No newline at end of file +.navbar[data-v-2d6400c2]{position:sticky;top:0;z-index:1000;width:100%;background:linear-gradient(90deg,#fff,#f8f9fa);box-shadow:0 2px 10px rgba(0,0,0,.05);height:64px}.navbar-container[data-v-2d6400c2]{max-width:1200px;margin:0 auto;padding:0 20px;height:100%;display:flex;align-items:center;justify-content:space-between}.navbar-brand[data-v-2d6400c2]{display:flex;align-items:center;cursor:pointer;transition:opacity .3s}.navbar-brand[data-v-2d6400c2]:hover{opacity:.8}.logo[data-v-2d6400c2]{height:40px;margin-right:12px}.brand-text[data-v-2d6400c2]{font-size:1.5rem;font-weight:700;color:#333;letter-spacing:.5px}.version-badge[data-v-2d6400c2]{background:linear-gradient(135deg,#225fc9,#5390e6);color:#fff;font-size:.75rem;padding:2px 8px;border-radius:12px;margin-left:10px;font-weight:700;box-shadow:0 2px 4px rgba(0,0,0,.2);position:relative;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;height:20px}.version-badge[data-v-2d6400c2]:after{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.4),transparent);transform:skewX(-20deg);animation:shine-2d6400c2 2s infinite}@keyframes shine-2d6400c2{0%{left:-100%}20%{left:200%}to{left:200%}}.navbar-menu[data-v-2d6400c2]{display:flex;gap:30px;align-items:center}.nav-item[data-v-2d6400c2]{text-decoration:none;color:#555;font-weight:500;font-size:16px;padding:8px 0;position:relative;transition:color .3s}.nav-item[data-v-2d6400c2]:hover{color:#409eff}.nav-item.active[data-v-2d6400c2]{color:#409eff;font-weight:600}.nav-item.active[data-v-2d6400c2]:after{content:"";position:absolute;bottom:0;left:0;width:100%;height:2px;background-color:#409eff;border-radius:2px}.navbar-toggle[data-v-2d6400c2]{background:none;border:none;cursor:pointer;padding:10px;display:none;margin-right:-10px}.hamburger-box[data-v-2d6400c2]{width:24px;height:24px;display:flex;align-items:center;justify-content:center;position:relative}.hamburger-inner[data-v-2d6400c2],.hamburger-inner[data-v-2d6400c2]:after,.hamburger-inner[data-v-2d6400c2]:before{width:24px;height:2px;background-color:#333;border-radius:2px;position:absolute;transition:transform .3s cubic-bezier(.4,.01,.165,.99),opacity .3s cubic-bezier(.4,.01,.165,.99),top .3s cubic-bezier(.4,.01,.165,.99),bottom .3s cubic-bezier(.4,.01,.165,.99);left:0}.hamburger-inner[data-v-2d6400c2]{top:50%;transform:translateY(-50%)}.hamburger-inner[data-v-2d6400c2]:before{content:"";top:-8px}.hamburger-inner[data-v-2d6400c2]:after{content:"";bottom:-8px}.hamburger-inner.is-active[data-v-2d6400c2]{transform:rotate(45deg)}.hamburger-inner.is-active[data-v-2d6400c2]:before{top:0;opacity:0}.hamburger-inner.is-active[data-v-2d6400c2]:after{bottom:0;transform:rotate(-90deg)}.mobile-menu-overlay[data-v-2d6400c2]{position:fixed;top:64px;left:0;width:100%;height:calc(100vh - 64px);background-color:rgba(0,0,0,.5);z-index:998}.mobile-menu-content[data-v-2d6400c2]{position:fixed;top:64px;left:0;right:0;background-color:#fff;z-index:999;box-shadow:0 4px 12px rgba(0,0,0,.1);padding:20px;display:flex;flex-direction:column;box-sizing:border-box}.mobile-menu-header[data-v-2d6400c2]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;border-bottom:1px solid #eee;padding-bottom:10px}.mobile-menu-title[data-v-2d6400c2]{font-size:1.2rem;font-weight:700;color:#333}.close-btn[data-v-2d6400c2]{font-size:2rem;line-height:1;cursor:pointer;color:#999}.mobile-links[data-v-2d6400c2]{display:flex;flex-direction:column;gap:15px}.mobile-nav-item[data-v-2d6400c2]{text-decoration:none;color:#333;font-size:1.1rem;padding:10px;border-radius:8px;background-color:#f9f9f9;text-align:center;transition:background-color .2s}.mobile-nav-item.active[data-v-2d6400c2]{background-color:#ecf5ff;color:#409eff;font-weight:600}.mobile-footer[data-v-2d6400c2]{margin-top:30px;text-align:center;color:#999;font-size:.8rem}@media (max-width:768px){.desktop-only[data-v-2d6400c2]{display:none}.mobile-only[data-v-2d6400c2]{display:block}.navbar-container[data-v-2d6400c2]{padding:0 15px}}.fade-enter-active[data-v-2d6400c2],.fade-leave-active[data-v-2d6400c2]{transition:opacity .3s}.fade-enter-from[data-v-2d6400c2],.fade-leave-to[data-v-2d6400c2]{opacity:0}.slide-down-enter-active[data-v-2d6400c2],.slide-down-leave-active[data-v-2d6400c2]{transition:transform .3s ease,opacity .3s}.slide-down-enter-from[data-v-2d6400c2],.slide-down-leave-to[data-v-2d6400c2]{transform:translateY(-20px);opacity:0}body,html{height:100%;margin:0;padding:0;background-color:#f5f7fa;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.app-layout{min-height:100vh;display:flex;flex-direction:column}.main-content{flex:1;padding:20px;width:100%;max-width:1200px;margin:0 auto;box-sizing:border-box}.forbidden-container{text-align:center;padding:50px 20px;display:flex;align-items:center;flex-direction:column;justify-content:center;min-height:100vh}.forbidden-title{color:#d9534f;font-size:2.5rem;margin-bottom:20px}.forbidden-text{font-size:1.25rem;color:#333;margin-bottom:30px;max-width:600px}.forbidden-back-btn{background-color:#5cb85c;color:#fff;padding:10px 20px;font-size:1.1rem;border:none;border-radius:5px;cursor:pointer;transition:background-color .3s ease}.forbidden-back-btn:hover{background-color:#4cae4c}@media (max-width:768px){.main-content{padding:15px}.forbidden-title{font-size:1.8rem}.forbidden-text{font-size:1rem}}h2[data-v-b5d4cca8]{color:#333;margin-bottom:10px;font-size:42px}@media (max-width:768px){h2[data-v-b5d4cca8]{font-size:28px}}p[data-v-b5d4cca8]{line-height:1.6;margin-bottom:15px;color:#666}.guide-link[data-v-b5d4cca8]{color:#0056b3;text-decoration:underline;cursor:pointer}.guide-link[data-v-b5d4cca8]:hover{color:#003d82}.course-list-page[data-v-2964ca48]{max-width:1200px;margin:0 auto;padding:20px;min-height:100vh;background-color:#f8f9fa}.page-title[data-v-2964ca48]{margin-bottom:20px;font-size:24px;color:#333;font-weight:700}.empty-message[data-v-2964ca48],.loading-message[data-v-2964ca48]{font-size:16px;color:#666;text-align:center;margin-top:40px}.course-cards[data-v-2964ca48]{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-bottom:40px}.course-card[data-v-2964ca48]{background:#fff;border-radius:12px;border:1px solid #f0f0f0;overflow:hidden;cursor:pointer;transition:all .3s ease;display:flex;flex-direction:column;height:100%;position:relative}.course-card[data-v-2964ca48]:hover{transform:translateY(-5px);box-shadow:0 8px 24px rgba(0,0,0,.08);border-color:#e0e0e0}.card-header[data-v-2964ca48]{padding:16px;border-bottom:1px solid #f9f9f9;display:flex;justify-content:space-between;align-items:flex-start;gap:10px}.course-name-title[data-v-2964ca48]{font-size:16px;font-weight:600;color:#333;margin:0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;flex:1}.status-tag[data-v-2964ca48]{font-size:12px;padding:2px 8px;border-radius:10px;white-space:nowrap;background:#eee;color:#666}.status-approved[data-v-2964ca48]{background:#e6f7ff;color:#1890ff;border:1px solid #91d5ff}.status-pending[data-v-2964ca48]{background:#fffbe6;color:#faad14;border:1px solid #ffe58f}.status-rejected[data-v-2964ca48]{background:#fff1f0;color:#f5222d;border:1px solid #ffa39e}.card-body[data-v-2964ca48]{padding:16px;flex:1}.info-row[data-v-2964ca48]{display:flex;justify-content:space-between;margin-bottom:8px;font-size:13px;color:#666}.info-label[data-v-2964ca48]{color:#999;margin-right:8px;flex-shrink:0}.info-val[data-v-2964ca48]{text-align:right;color:#333;font-weight:500}.truncate[data-v-2964ca48]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%}.card-footer[data-v-2964ca48]{padding:12px 16px;background:#fafafa;border-top:1px solid #f0f0f0}.time-info[data-v-2964ca48]{display:flex;flex-direction:column;gap:4px}.time-row[data-v-2964ca48]{display:flex;justify-content:space-between;font-size:12px;color:#999}.pagination-bar[data-v-2964ca48]{display:flex;justify-content:center;gap:8px;margin-bottom:40px;flex-wrap:wrap}.pagination-bar button[data-v-2964ca48]{min-width:36px;height:36px;padding:0 10px;border:1px solid #e0e0e0;background:#fff;color:#606266;border-radius:6px;cursor:pointer;transition:all .2s;font-size:14px}.pagination-bar button[data-v-2964ca48]:hover:not(:disabled){color:#409eff;border-color:#409eff}.pagination-bar button.active[data-v-2964ca48]{background-color:#409eff;border-color:#409eff;color:#fff}.pagination-bar button[data-v-2964ca48]:disabled{background:#f5f7fa;color:#c0c4cc;cursor:not-allowed}.add-course-section[data-v-2964ca48]{background:#fff;border-radius:12px;padding:24px;box-shadow:0 2px 12px rgba(0,0,0,.05);margin-top:40px}.section-header[data-v-2964ca48]{display:flex;align-items:center;gap:15px;margin-bottom:20px}.section-header h2[data-v-2964ca48]{margin:0;font-size:20px;color:#333}.help-btn[data-v-2964ca48]{display:flex;align-items:center;gap:5px;padding:5px 10px;background:#f8f9fa;border:1px solid #dee2e6;border-radius:4px;cursor:pointer;font-size:14px;color:#495057;transition:all .2s ease}.help-btn[data-v-2964ca48]:hover{background:#e9ecef}.help-icon[data-v-2964ca48]{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background:#6c757d;color:#fff;font-size:12px;font-weight:700}.input-grid[data-v-2964ca48]{display:grid;grid-template-columns:repeat(2,1fr);gap:30px}.input-group[data-v-2964ca48]{display:flex;flex-direction:column;gap:8px}.input-group label[data-v-2964ca48]{font-size:14px;color:#606266;font-weight:500}.modern-input[data-v-2964ca48],.modern-select[data-v-2964ca48]{width:100%;box-sizing:border-box;padding:10px;border:1px solid #e0e0e0;border-radius:8px;font-size:14px;transition:all .3s;background:#fff}.modern-input[data-v-2964ca48]:focus,.modern-select[data-v-2964ca48]:focus{border-color:#409eff;box-shadow:0 0 0 2px rgba(64,158,255,.2);outline:none}.button-group[data-v-2964ca48]{grid-column:1/-1;display:flex;justify-content:flex-end;margin-top:10px}.submit-btn[data-v-2964ca48]{padding:10px 30px;background-color:#409eff;color:#fff;border:none;border-radius:8px;font-weight:500;cursor:pointer;transition:all .3s}.submit-btn[data-v-2964ca48]:hover{background-color:#66b1ff;transform:translateY(-1px)}.help-modal[data-v-2964ca48]{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center;z-index:1000}.help-modal-content[data-v-2964ca48]{background:#fff;border-radius:12px;width:90%;max-width:600px;max-height:80vh;overflow-y:auto;padding:20px;box-shadow:0 4px 6px rgba(0,0,0,.1)}.help-modal-header[data-v-2964ca48]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #dee2e6}.close-btn[data-v-2964ca48]{background:none;border:none;font-size:24px;cursor:pointer;color:#6c757d}.help-section[data-v-2964ca48]{margin-bottom:20px}.help-modal-header h3[data-v-2964ca48]{font-size:20px;font-weight:700;margin:0}.help-section h4[data-v-2964ca48]{color:#0056b3;margin-bottom:10px}.help-section p[data-v-2964ca48]{color:#495057;line-height:1.6;margin-bottom:8px}@media (max-width:768px){.course-cards[data-v-2964ca48]{grid-template-columns:repeat(2,1fr);gap:12px}.input-grid[data-v-2964ca48]{grid-template-columns:1fr}.course-name-title[data-v-2964ca48]{font-size:14px}.status-tag[data-v-2964ca48]{font-size:10px;padding:1px 5px}}@media (max-width:480px){.course-cards[data-v-2964ca48]{grid-template-columns:1fr}}.rating-page[data-v-7d8ad36d]{max-width:1200px;margin:0 auto;padding:20px;background-color:#f8f9fa;min-height:100vh}.rating-note[data-v-7d8ad36d]{font-size:14px;color:#666;margin-bottom:20px;text-align:center}.search-sort-bar[data-v-7d8ad36d]{background:#fff;border-radius:12px;padding:20px;margin-bottom:30px;box-shadow:0 2px 12px rgba(0,0,0,.05);display:flex;flex-direction:column;gap:20px}.search-inputs[data-v-7d8ad36d]{display:flex;gap:15px}.input-wrapper[data-v-7d8ad36d]{position:relative;flex:1;display:flex;align-items:center}.search-icon[data-v-7d8ad36d]{position:absolute;left:12px;color:#999;font-size:16px}.modern-input[data-v-7d8ad36d]{width:100%;padding:10px 10px 10px 36px;border:1px solid #e0e0e0;border-radius:8px;font-size:14px;transition:all .3s}.modern-input[data-v-7d8ad36d]:focus{border-color:#409eff;box-shadow:0 0 0 2px rgba(64,158,255,.2);outline:none}.teacher-input[data-v-7d8ad36d]{flex:1.5}.filters-row[data-v-7d8ad36d]{border-top:1px solid #f0f0f0;padding-top:15px}.category-checkboxes[data-v-7d8ad36d]{display:flex;flex-wrap:wrap;gap:15px}.checkbox-label[data-v-7d8ad36d]{display:flex;align-items:center;cursor:pointer;font-size:14px;color:#555;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:6px 12px;background:#f5f7fa;border-radius:20px;transition:all .2s}.checkbox-label[data-v-7d8ad36d]:hover{background:#e6e8eb}.checkbox-label input[data-v-7d8ad36d]{margin-right:6px}.actions-row[data-v-7d8ad36d]{display:flex;justify-content:space-between;align-items:center;border-top:1px solid #f0f0f0;padding-top:15px}.select-group[data-v-7d8ad36d]{display:flex;gap:15px}.modern-select[data-v-7d8ad36d]{padding:8px 12px;border:1px solid #e0e0e0;border-radius:6px;font-size:14px;color:#555;background:#fff;cursor:pointer}.search-btn[data-v-7d8ad36d]{padding:8px 24px;background-color:#409eff;color:#fff;border:none;border-radius:6px;font-weight:500;cursor:pointer;transition:all .3s}.search-btn[data-v-7d8ad36d]:hover{background-color:#66b1ff;transform:translateY(-1px)}.course-cards[data-v-7d8ad36d]{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-bottom:30px}.course-card[data-v-7d8ad36d]{background:#fff;border-radius:12px;border:1px solid #f0f0f0;overflow:hidden;cursor:pointer;transition:all .3s ease;display:flex;flex-direction:column;position:relative;height:100%}.course-card[data-v-7d8ad36d]:hover{transform:translateY(-5px);box-shadow:0 8px 24px rgba(0,0,0,.08);border-color:#e0e0e0}.card-header[data-v-7d8ad36d]{padding:16px;border-bottom:1px solid #f9f9f9}.course-name-title[data-v-7d8ad36d]{font-size:16px;font-weight:600;color:#333;margin:0 0 8px 0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;height:44px}.course-tags[data-v-7d8ad36d]{display:flex;flex-wrap:wrap;gap:6px}.mini-tag[data-v-7d8ad36d]{font-size:10px;padding:2px 6px;border:1px solid;border-radius:4px;white-space:nowrap}.card-body[data-v-7d8ad36d]{padding:16px;flex:1}.info-row[data-v-7d8ad36d]{display:flex;justify-content:space-between;margin-bottom:8px;font-size:13px;color:#666}.info-label[data-v-7d8ad36d]{color:#999;margin-right:8px;flex-shrink:0}.info-val[data-v-7d8ad36d]{text-align:right;color:#333;font-weight:500}.truncate[data-v-7d8ad36d]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%}.card-footer[data-v-7d8ad36d]{padding:12px 16px;background:#fafafa;border-top:1px solid #f0f0f0}.rating-info[data-v-7d8ad36d]{display:flex;align-items:baseline;margin-bottom:8px}.score[data-v-7d8ad36d]{font-size:24px;font-weight:700;color:#f90;line-height:1}.score-label[data-v-7d8ad36d]{font-size:12px;color:#f90;margin-left:2px}.count[data-v-7d8ad36d]{font-size:12px;color:#999;margin-left:auto}.top-comment[data-v-7d8ad36d]{font-size:12px;color:#666;background:#fff;padding:8px;border-radius:6px;font-style:italic;line-height:1.4;border:1px solid #eee;height:50px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.top-comment.placeholder[data-v-7d8ad36d]{color:#ccc;font-style:normal;display:flex;align-items:center;justify-content:center}.pagination-bar[data-v-7d8ad36d]{display:flex;justify-content:center;gap:8px;margin-top:30px}.pagination-bar button[data-v-7d8ad36d]{min-width:36px;height:36px;padding:0 10px;border:1px solid #e0e0e0;background:#fff;color:#606266;border-radius:6px;cursor:pointer;transition:all .2s;font-size:14px}.pagination-bar button[data-v-7d8ad36d]:hover:not(:disabled){color:#409eff;border-color:#409eff}.pagination-bar button.active[data-v-7d8ad36d]{background-color:#409eff;border-color:#409eff;color:#fff}.pagination-bar button[data-v-7d8ad36d]:disabled{background:#f5f7fa;color:#c0c4cc;cursor:not-allowed}@media (max-width:768px){.course-cards[data-v-7d8ad36d]{grid-template-columns:repeat(2,1fr);gap:12px}.search-sort-bar[data-v-7d8ad36d]{padding:15px}.search-inputs[data-v-7d8ad36d]{flex-direction:column}.actions-row[data-v-7d8ad36d]{flex-direction:column;gap:15px}.select-group[data-v-7d8ad36d]{width:100%;flex-direction:column;gap:10px}.modern-select[data-v-7d8ad36d]{width:100%}.pagination-bar[data-v-7d8ad36d]{flex-wrap:wrap}.search-btn[data-v-7d8ad36d]{width:100%}.course-name-title[data-v-7d8ad36d]{font-size:14px;height:40px}.info-row[data-v-7d8ad36d]{font-size:12px}.score[data-v-7d8ad36d]{font-size:20px}}.rating-page[data-v-3228e625]{max-width:1200px;margin:0 auto;padding:20px;background-color:#f8f9fa;min-height:100vh}.rating-note[data-v-3228e625]{font-size:14px;color:#666;margin-bottom:20px;text-align:center}.search-sort-bar[data-v-3228e625]{background:#fff;border-radius:12px;padding:20px;margin-bottom:30px;box-shadow:0 2px 12px rgba(0,0,0,.05);display:flex;flex-direction:column;gap:20px}.search-inputs[data-v-3228e625]{display:flex;gap:15px}.input-wrapper[data-v-3228e625]{position:relative;flex:1;display:flex;align-items:center}.search-icon[data-v-3228e625]{position:absolute;left:12px;color:#999;font-size:16px}.modern-input[data-v-3228e625]{width:100%;padding:10px 10px 10px 36px;border:1px solid #e0e0e0;border-radius:8px;font-size:14px;transition:all .3s}.modern-input[data-v-3228e625]:focus{border-color:#409eff;box-shadow:0 0 0 2px rgba(64,158,255,.2);outline:none}.teacher-input[data-v-3228e625]{flex:1.5}.filters-row[data-v-3228e625]{border-top:1px solid #f0f0f0;padding-top:15px}.category-checkboxes[data-v-3228e625]{display:flex;flex-wrap:wrap;gap:15px}.checkbox-label[data-v-3228e625]{display:flex;align-items:center;cursor:pointer;font-size:14px;color:#555;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:6px 12px;background:#f5f7fa;border-radius:20px;transition:all .2s}.checkbox-label[data-v-3228e625]:hover{background:#e6e8eb}.checkbox-label input[data-v-3228e625]{margin-right:6px}.actions-row[data-v-3228e625]{display:flex;justify-content:space-between;align-items:center;border-top:1px solid #f0f0f0;padding-top:15px}.select-group[data-v-3228e625]{display:flex;gap:15px}.modern-select[data-v-3228e625]{padding:8px 12px;border:1px solid #e0e0e0;border-radius:6px;font-size:14px;color:#555;background:#fff;cursor:pointer}.search-btn[data-v-3228e625]{padding:8px 24px;background-color:#409eff;color:#fff;border:none;border-radius:6px;font-weight:500;cursor:pointer;transition:all .3s}.search-btn[data-v-3228e625]:hover{background-color:#66b1ff;transform:translateY(-1px)}.course-cards[data-v-3228e625]{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-bottom:30px}.course-card[data-v-3228e625]{background:#fff;border-radius:12px;border:1px solid #f0f0f0;overflow:hidden;cursor:pointer;transition:all .3s ease;display:flex;flex-direction:column;position:relative;height:100%}.course-card[data-v-3228e625]:hover{transform:translateY(-5px);box-shadow:0 8px 24px rgba(0,0,0,.08);border-color:#e0e0e0}.card-header[data-v-3228e625]{padding:16px;border-bottom:1px solid #f9f9f9}.course-name-title[data-v-3228e625]{font-size:16px;font-weight:600;color:#333;margin:0 0 8px 0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;height:44px}.course-tags[data-v-3228e625]{display:flex;flex-wrap:wrap;gap:6px}.mini-tag[data-v-3228e625]{font-size:10px;padding:2px 6px;border:1px solid;border-radius:4px;white-space:nowrap}.card-body[data-v-3228e625]{padding:16px;flex:1}.info-row[data-v-3228e625]{display:flex;justify-content:space-between;margin-bottom:8px;font-size:13px;color:#666}.info-label[data-v-3228e625]{color:#999;margin-right:8px;flex-shrink:0}.info-val[data-v-3228e625]{text-align:right;color:#333;font-weight:500}.truncate[data-v-3228e625]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%}.card-footer[data-v-3228e625]{padding:12px 16px;background:#fafafa;border-top:1px solid #f0f0f0}.rating-info[data-v-3228e625]{display:flex;align-items:baseline;margin-bottom:8px}.score[data-v-3228e625]{font-size:24px;font-weight:700;color:#f90;line-height:1}.score-label[data-v-3228e625]{font-size:12px;color:#f90;margin-left:2px}.count[data-v-3228e625]{font-size:12px;color:#999;margin-left:auto}.top-comment[data-v-3228e625]{font-size:12px;color:#666;background:#fff;padding:8px;border-radius:6px;font-style:italic;line-height:1.4;border:1px solid #eee;height:50px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.top-comment.placeholder[data-v-3228e625]{color:#ccc;font-style:normal;display:flex;align-items:center;justify-content:center}.pagination-bar[data-v-3228e625]{display:flex;justify-content:center;gap:8px;margin-top:30px}.pagination-bar button[data-v-3228e625]{min-width:36px;height:36px;padding:0 10px;border:1px solid #e0e0e0;background:#fff;color:#606266;border-radius:6px;cursor:pointer;transition:all .2s;font-size:14px}.pagination-bar button[data-v-3228e625]:hover:not(:disabled){color:#409eff;border-color:#409eff}.pagination-bar button.active[data-v-3228e625]{background-color:#409eff;border-color:#409eff;color:#fff}.pagination-bar button[data-v-3228e625]:disabled{background:#f5f7fa;color:#c0c4cc;cursor:not-allowed}@media (max-width:768px){.course-cards[data-v-3228e625]{grid-template-columns:repeat(2,1fr);gap:12px}.search-sort-bar[data-v-3228e625]{padding:15px}.search-inputs[data-v-3228e625]{flex-direction:column}.actions-row[data-v-3228e625]{flex-direction:column;gap:15px}.select-group[data-v-3228e625]{width:100%;flex-direction:column;gap:10px}.modern-select[data-v-3228e625]{width:100%}.pagination-bar[data-v-3228e625]{flex-wrap:wrap}.search-btn[data-v-3228e625]{width:100%}.course-name-title[data-v-3228e625]{font-size:14px;height:40px}.info-row[data-v-3228e625]{font-size:12px}.score[data-v-3228e625]{font-size:20px}}.modal-overlay[data-v-9c153036]{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center;z-index:999}.loading[data-v-9c153036]{display:flex;align-items:center;justify-content:center;flex-direction:column;text-align:center;height:200px}.el-icon[data-v-9c153036]{font-size:40px;margin-bottom:10px}.modal-content[data-v-9c153036]{background-color:#fff;padding:20px;border-radius:8px;width:80%;height:80%;display:flex;flex-direction:row;justify-content:space-between;position:relative}.close[data-v-9c153036]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.course-detail[data-v-9c153036]{max-height:calc(90vh - 120px);overflow-y:auto;overflow-x:auto;padding-right:15px;width:40%}.course-detail[data-v-9c153036]::-webkit-scrollbar{width:6px;height:6px}.course-detail[data-v-9c153036]::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.course-detail[data-v-9c153036]::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.course-detail[data-v-9c153036]::-webkit-scrollbar-thumb:hover{background:#555}.course-detail[data-v-9c153036]>*{min-width:-moz-fit-content;min-width:fit-content}.rating-section[data-v-9c153036]{margin-top:20px}.total-rating[data-v-9c153036]{font-size:40px;margin-bottom:10px}.stars span[data-v-9c153036]{font-size:30px;cursor:pointer;transition:color .3s}.stars .highlighted[data-v-9c153036]{color:gold}.stars span[data-v-9c153036]:not(.highlighted){color:#ccc}.comment-section[data-v-9c153036]{width:55%;padding-left:20px}.comments-list[data-v-9c153036]{max-height:350px;overflow-y:auto;margin-bottom:20px}.comment[data-v-9c153036]{padding:10px 0;border-bottom:1px solid #ddd}.like-section[data-v-9c153036]{cursor:pointer;color:gray}.like-section.liked[data-v-9c153036]{color:red}.new-comment[data-v-9c153036]{display:flex;flex-direction:column}.new-comment input[data-v-9c153036],.new-comment textarea[data-v-9c153036]{margin-bottom:10px;padding:5px;border-radius:5px;border:1px solid #ccc}.new-comment button[data-v-9c153036]{padding:10px;background-color:#007bff;color:#fff;border:none;border-radius:5px;cursor:pointer}.comment-meta[data-v-9c153036],.comment-time[data-v-9c153036]{font-size:13px}.progress[data-v-9c153036]{margin-bottom:5px;width:250px}[data-v-9c153036] .progress .el-progress-bar__outer{height:20px!important;line-height:40px;background-color:#a19999}.course-title[data-v-9c153036]{display:inline-flex;align-items:center;justify-content:center;padding:2px 6px;border:1px solid;border-radius:12px;margin-left:4px;font-size:.85em;min-height:20px}.share-btn[data-v-9c153036]{background-color:#4caf50;color:#fff;border:none;padding:6px 12px;margin-left:10px;border-radius:4px;cursor:pointer;font-size:14px}.share-btn[data-v-9c153036]:hover{background-color:#45a049}.error-modal[data-v-9c153036],.share-modal[data-v-9c153036]{position:fixed;top:20%;left:50%;transform:translateX(-50%);color:#fff;padding:15px;border-radius:10px;text-align:center;box-shadow:0 4px 8px rgba(0,0,0,.1);font-size:16px;z-index:9999;animation:fadeInDown-9c153036 .5s ease}.share-modal[data-v-9c153036]{background-color:#4caf50}.error-modal[data-v-9c153036]{background-color:#f44}@keyframes fadeInDown-9c153036{0%{opacity:0;transform:translate(-50%,-30px)}to{opacity:1;transform:translate(-50%)}}.chat-start-btn[data-v-9c153036]{margin-left:10px;padding:5px 10px;background-color:#409eff;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color .3s ease,transform .2s ease}.chat-start-btn[data-v-9c153036]:hover{background-color:#66b1ff;transform:scale(1.05)}.chat-start-btn[data-v-9c153036]:active{background-color:#3a8ee6;transform:scale(.95)}.chat-modal-overlay[data-v-9c153036]{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;justify-content:center;align-items:center;z-index:1000;animation:chat-fadeIn-9c153036 .3s ease}.chat-modal-content[data-v-9c153036]{background:#fff;padding:20px;border-radius:8px;width:400px;box-shadow:0 2px 10px rgba(0,0,0,.1);text-align:center;animation:chat-slideIn-9c153036 .3s ease;position:relative}.chat-modal-content .chat-close-btn[data-v-9c153036]{position:absolute;top:10px;right:15px;font-size:20px;color:#999;cursor:pointer;transition:color .3s ease}.chat-modal-content .chat-close-btn[data-v-9c153036]:hover{color:#333}.chat-modal-content h3[data-v-9c153036]{margin-top:0;color:#333;font-size:18px}.chat-modal-actions[data-v-9c153036]{margin-top:20px;display:flex;justify-content:space-around}.chat-modal-actions button[data-v-9c153036]{padding:10px 20px;font-size:14px;border:none;border-radius:4px;cursor:pointer;transition:background-color .3s ease,transform .2s ease}.chat-modal-actions button[data-v-9c153036]:first-child{background-color:#409eff;color:#fff}.chat-modal-actions button[data-v-9c153036]:first-child:hover{background-color:#66b1ff}.chat-modal-actions button[data-v-9c153036]:first-child:active{background-color:#3a8ee6}.chat-modal-actions button[data-v-9c153036]:last-child{background-color:#f5f5f5;color:#666}.chat-modal-actions button[data-v-9c153036]:last-child:hover{background-color:#e0e0e0}.chat-modal-actions button[data-v-9c153036]:last-child:active{background-color:#d6d6d6}.chat-textarea[data-v-9c153036]{border:1px solid #dcdfe6;border-radius:4px;padding:10px;font-size:14px;width:100%;height:100px;box-sizing:border-box;resize:none;outline:none;transition:border-color .3s ease}.chat-textarea[data-v-9c153036]:focus{border-color:#409eff}@keyframes chat-fadeIn-9c153036{0%{opacity:0}to{opacity:1}}@keyframes chat-slideIn-9c153036{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}.delete-btn[data-v-9c153036]{color:red;background:none;border:none;cursor:pointer;margin-left:10px;font-size:14px;padding:2px 8px}.delete-btn[data-v-9c153036]:hover{text-decoration:underline}.comment-actions[data-v-9c153036]{display:flex;align-items:center;margin-top:10px;font-size:14px}.ai-summary[data-v-9c153036]{margin-top:15px;padding:10px;background-color:#f5f5f5;border-radius:4px;line-height:1.5}.typing-cursor[data-v-9c153036]{display:inline-block;width:6px;height:14px;background-color:#000;animation:blink-9c153036 1s step-start infinite;margin-left:2px;vertical-align:middle}@keyframes blink-9c153036{50%{opacity:0}}@media (max-width:768px){.modal-content[data-v-9c153036]{width:95%;height:95%;flex-direction:column;overflow-y:auto}.course-detail[data-v-9c153036]{width:100%;height:auto;max-height:none;border-right:none;border-bottom:1px solid #eee;padding-right:0;padding-bottom:20px;margin-bottom:20px}.comment-section[data-v-9c153036]{width:100%;padding-left:0}.total-rating[data-v-9c153036]{font-size:32px}.chat-modal-content[data-v-9c153036]{width:90%}}.chat-page[data-v-38851032]{display:flex;height:98vh;overflow:hidden}.sidebar[data-v-38851032]{width:300px;border-right:1px solid #ddd;display:flex;flex-direction:column;padding:10px;background-color:#f9f9f9}.sidebar h3[data-v-38851032]{margin-bottom:10px}.conversation-item[data-v-38851032]{padding:10px;margin:5px 0;border-radius:5px;cursor:pointer;background-color:#fff;transition:background-color .2s}.conversation-item[data-v-38851032]:hover{background-color:#f0f0f0}.conversation-item.active[data-v-38851032]{background-color:#e6f7ff;border-left:4px solid #1890ff}.conversation-name[data-v-38851032]{font-weight:700;display:flex;align-items:center}.role-label[data-v-38851032]{color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.role-label.owner[data-v-38851032]{background-color:#2196f3}.role-label.member[data-v-38851032]{background-color:#4caf50}.conversation-last-message[data-v-38851032],.conversation-updated-at[data-v-38851032]{color:#999;font-size:12px}.new-message-label[data-v-38851032]{background-color:red;color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.chat-container[data-v-38851032]{flex:1;display:flex;flex-direction:column;background-color:#f5f5f5;width:48.5vw;height:98vh;position:relative}.conversation-info[data-v-38851032]{padding:10px;background-color:#fff;border-bottom:1px solid #ddd;display:flex;justify-content:space-between;align-items:center}.message-list[data-v-38851032]{flex:1;padding:10px;overflow-y:auto}.message[data-v-38851032]{margin:10px 0;display:flex;flex-direction:column}.message.self[data-v-38851032]{align-items:flex-end}.message.other[data-v-38851032]{align-items:flex-start}.message-bubble[data-v-38851032]{max-width:60%;padding:10px;border-radius:8px;background-color:#fff;box-shadow:0 1px 3px rgba(0,0,0,.1);position:relative}.message.self .message-bubble[data-v-38851032]{background-color:#daf1da}.message-info[data-v-38851032]{display:flex;margin-top:5px}.message-info.align-right[data-v-38851032]{justify-content:flex-end}.message-info.align-left[data-v-38851032]{justify-content:flex-start}.message-info small[data-v-38851032]{color:#999;font-size:12px;margin-left:5px}.input-container[data-v-38851032]{padding:10px;border-top:1px solid #ddd;text-align:center}.locked-input[data-v-38851032]{height:60px}.locked-input[data-v-38851032] .el-textarea__inner{resize:none!important}.header[data-v-38851032]{display:flex;justify-content:space-between;align-items:center}.connection-status[data-v-38851032]{display:flex;align-items:center;font-size:14px}.status-indicator[data-v-38851032]{width:8px;height:8px;border-radius:50%;margin-right:5px}.status-indicator.connected[data-v-38851032]{background-color:#02f23e}.status-indicator.disconnected[data-v-38851032]{background-color:#f44336}.status-text[data-v-38851032]{font-size:14px;font-weight:400}.connected .status-text[data-v-38851032]{color:#02f23e}.disconnected .status-text[data-v-38851032]{color:#f44336}.mobile-back-btn[data-v-38851032]{display:none;background:none;border:none;color:#007bff;font-size:16px;cursor:pointer;padding:0 10px 0 0;margin-right:10px}@media (max-width:768px){.chat-page[data-v-38851032]{height:calc(100vh - 64px)}.sidebar[data-v-38851032]{width:100%;border-right:none}.chat-container[data-v-38851032]{width:100%;height:100%;display:none}.chat-page.mobile-chat-active .sidebar[data-v-38851032]{display:none}.chat-page.mobile-chat-active .chat-container[data-v-38851032]{display:flex}.mobile-back-btn[data-v-38851032]{display:inline-block}.message-bubble[data-v-38851032]{max-width:80%}.conversation-info[data-v-38851032]{flex-wrap:wrap;gap:10px}}.about-container[data-v-5c1b02c2]{height:90vh;overflow:hidden;padding:20px}.about-page[data-v-5c1b02c2]{max-width:99%;margin:0 auto;height:100%;overflow-y:auto;padding-right:15px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar{width:6px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.about-page[data-v-5c1b02c2]::-webkit-scrollbar-thumb:hover{background:#555}.project-intro[data-v-5c1b02c2]{margin-bottom:40px}h2[data-v-5c1b02c2]{color:#333;margin-bottom:20px;font-size:24px;border-bottom:2px solid #eee;padding-bottom:10px}.intro-content[data-v-5c1b02c2]{line-height:1.8;color:#666}.intro-content p[data-v-5c1b02c2]{margin-bottom:15px}.version-timeline[data-v-5c1b02c2]{margin-top:40px}.version-item[data-v-5c1b02c2]{background-color:#f8f9fa;padding:15px;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,.05);margin-bottom:10px}.version-item h4[data-v-5c1b02c2]{color:#409eff;margin:0 0 10px 0}.version-item p[data-v-5c1b02c2]{color:#666;margin:0}.version-item ul[data-v-5c1b02c2]{list-style-type:disc;margin:0;padding-left:20px}.version-item li[data-v-5c1b02c2]{margin-bottom:5px}[data-v-5c1b02c2] .el-timeline-item__node{background-color:#409eff}[data-v-5c1b02c2] .el-timeline-item__timestamp{color:#409eff;font-weight:700}@media (max-width:768px){.about-container[data-v-5c1b02c2]{height:auto;overflow:visible;padding:10px}.about-page[data-v-5c1b02c2]{overflow-y:visible;height:auto}}.course-detail-page[data-v-2adb15a0]{background-color:#f5f7fa;min-height:100vh;padding-bottom:40px}.container[data-v-2adb15a0]{max-width:1200px;margin:0 auto;padding:20px}.loading-state[data-v-2adb15a0]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:60vh;color:#666}.spinner[data-v-2adb15a0]{border:4px solid #f3f3f3;border-top:4px solid #409eff;border-radius:50%;width:40px;height:40px;animation:spin-2adb15a0 1s linear infinite;margin-bottom:15px}@keyframes spin-2adb15a0{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.card[data-v-2adb15a0]{background:#fff;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,.05);padding:24px;margin-bottom:24px;transition:all .3s ease}.card[data-v-2adb15a0]:hover{box-shadow:0 4px 16px rgba(0,0,0,.08)}.top-section[data-v-2adb15a0]{display:grid;grid-template-columns:1.2fr .8fr;gap:24px}.card-header[data-v-2adb15a0]{margin-bottom:20px}.course-name[data-v-2adb15a0]{font-size:24px;color:#333;margin:0;display:flex;align-items:center;flex-wrap:wrap;gap:10px}.tags[data-v-2adb15a0]{display:flex;gap:8px}.tag[data-v-2adb15a0]{font-size:12px;padding:2px 8px;border:1px solid;border-radius:12px;white-space:nowrap}.info-grid[data-v-2adb15a0]{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:24px}.info-item[data-v-2adb15a0]{display:flex;flex-direction:column}.info-item.full-width[data-v-2adb15a0]{grid-column:1/-1}.label[data-v-2adb15a0]{font-size:13px;color:#909399;margin-bottom:4px}.value[data-v-2adb15a0]{font-size:16px;color:#303133;font-weight:500}.share-btn[data-v-2adb15a0]{background-color:#ecf5ff;color:#409eff;border:none;padding:10px 20px;border-radius:20px;cursor:pointer;font-weight:500;display:inline-flex;align-items:center;gap:6px;transition:background .2s}.share-btn[data-v-2adb15a0]:hover{background-color:#d9ecff}.rating-overview[data-v-2adb15a0]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.total-score[data-v-2adb15a0]{display:flex;align-items:baseline;gap:8px}.score[data-v-2adb15a0]{font-size:48px;font-weight:700;color:#409eff;line-height:1}.count[data-v-2adb15a0]{color:#909399;font-size:14px}.user-rating-action p[data-v-2adb15a0]{margin:0 0 5px 0;font-size:13px;color:#606266;text-align:center}.stars[data-v-2adb15a0]{color:#ddd;font-size:24px;cursor:pointer}.stars.interactive span.active[data-v-2adb15a0],.stars.interactive span[data-v-2adb15a0]:hover{color:#f7ba2a}.bar-row[data-v-2adb15a0]{display:flex;align-items:center;gap:10px;margin-bottom:8px;font-size:13px}.star-label[data-v-2adb15a0]{width:30px;color:#606266}.el-progress[data-v-2adb15a0]{flex:1}.percent[data-v-2adb15a0]{width:35px;text-align:right;color:#909399}.section-header[data-v-2adb15a0]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;border-bottom:1px solid #ebeef5;padding-bottom:15px}.section-header h2[data-v-2adb15a0]{font-size:18px;margin:0;display:flex;align-items:center;gap:8px}.beta-badge[data-v-2adb15a0]{background:#f56c6c;color:#fff;font-size:10px;padding:2px 6px;border-radius:4px;vertical-align:top}.ai-disclaimer[data-v-2adb15a0]{font-size:12px;color:#909399}.ai-content[data-v-2adb15a0]{line-height:1.6;color:#303133;min-height:80px}.cursor[data-v-2adb15a0]{animation:blink-2adb15a0 1s infinite}@keyframes blink-2adb15a0{50%{opacity:0}}.sort-tabs[data-v-2adb15a0]{display:flex;gap:10px;font-size:14px;color:#909399}.sort-tabs span[data-v-2adb15a0]{cursor:pointer}.sort-tabs span.active[data-v-2adb15a0]{color:#409eff;font-weight:700}.divider[data-v-2adb15a0]{color:#ebeef5;cursor:default!important}.post-comment[data-v-2adb15a0]{background:#f9fafc;padding:20px;border-radius:8px;margin-bottom:30px}.input-group[data-v-2adb15a0]{display:flex;flex-direction:column;gap:10px;margin-bottom:10px}.nickname-input[data-v-2adb15a0]{padding:8px 12px;border:1px solid #dcdfe6;border-radius:4px;width:200px}.comment-textarea[data-v-2adb15a0]{padding:10px 12px;border:1px solid #dcdfe6;border-radius:4px;min-height:80px;resize:vertical}.submit-btn[data-v-2adb15a0]{background:#409eff;color:#fff;border:none;padding:8px 24px;border-radius:4px;cursor:pointer;align-self:flex-end}.comment-item[data-v-2adb15a0]{border-bottom:1px solid #ebeef5;padding:20px 0}.comment-item[data-v-2adb15a0]:last-child{border-bottom:none}.comment-header[data-v-2adb15a0]{display:flex;justify-content:space-between;margin-bottom:8px}.comment-author[data-v-2adb15a0]{font-weight:700;color:#303133}.comment-date[data-v-2adb15a0]{font-size:12px;color:#909399}.comment-body[data-v-2adb15a0]{font-size:14px;color:#606266;margin-bottom:12px;white-space:pre-wrap}.comment-footer[data-v-2adb15a0]{display:flex;justify-content:space-between;align-items:center;font-size:13px}.rating-tag span[data-v-2adb15a0]{color:#f56c6c;font-weight:700}.actions[data-v-2adb15a0]{display:flex;gap:15px}.like-btn[data-v-2adb15a0]{cursor:pointer;color:#909399}.like-btn.liked[data-v-2adb15a0]{color:#f56c6c}.action-link[data-v-2adb15a0]{background:none;border:none;cursor:pointer;font-size:13px}.action-link.delete[data-v-2adb15a0]{color:#f56c6c}.action-link.chat[data-v-2adb15a0]{color:#409eff}.toast[data-v-2adb15a0]{position:fixed;top:80px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.8);color:#fff;padding:10px 20px;border-radius:4px;z-index:2000}.modal-overlay[data-v-2adb15a0]{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:2000}.modal-box[data-v-2adb15a0]{background:#fff;width:90%;max-width:400px;padding:24px;border-radius:8px;position:relative}.close-btn[data-v-2adb15a0]{position:absolute;right:15px;top:10px;font-size:24px;cursor:pointer;color:#909399}.modal-textarea[data-v-2adb15a0]{width:90%;min-height:100px;margin:15px 0;padding:10px;border:1px solid #dcdfe6;border-radius:4px;resize:none}.modal-actions[data-v-2adb15a0]{display:flex;justify-content:flex-end;gap:10px}.primary-btn[data-v-2adb15a0]{background:#409eff;color:#fff;border:none;padding:8px 20px;border-radius:4px;cursor:pointer}.secondary-btn[data-v-2adb15a0]{background:#fff;border:1px solid #dcdfe6;padding:8px 20px;border-radius:4px;cursor:pointer}@media (max-width:768px){.top-section[data-v-2adb15a0]{grid-template-columns:1fr;gap:16px}.info-grid[data-v-2adb15a0]{grid-template-columns:1fr}.rating-overview[data-v-2adb15a0]{flex-direction:column;align-items:flex-start;gap:15px}.user-rating-action[data-v-2adb15a0]{width:100%;display:flex;justify-content:space-between;align-items:center}.score[data-v-2adb15a0]{font-size:36px}.nickname-input[data-v-2adb15a0]{width:100%}}.not-found-page[data-v-655c3ea4]{display:flex;justify-content:center;align-items:center;min-height:80vh;text-align:center;background-color:#f5f7fa;padding:20px}.content[data-v-655c3ea4]{background:#fff;padding:40px 60px;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,.1);max-width:500px;width:100%}.error-icon[data-v-655c3ea4]{font-size:64px;margin-bottom:20px}.error-code[data-v-655c3ea4]{font-size:72px;font-weight:700;color:#409eff;margin:0;line-height:1}.error-message[data-v-655c3ea4]{font-size:24px;color:#303133;margin:10px 0 20px;font-weight:500}.description[data-v-655c3ea4]{color:#606266;margin-bottom:30px;font-size:16px}.home-btn[data-v-655c3ea4]{display:inline-block;padding:12px 24px;background-color:#409eff;color:#fff;text-decoration:none;border-radius:6px;transition:background-color .3s;font-weight:500}.home-btn[data-v-655c3ea4]:hover{background-color:#66b1ff}body{font-family:Microsoft YaHei,微软雅黑,Arial,sans-serif;margin:0;padding:0}*{font-family:inherit} \ No newline at end of file diff --git a/dist/index.html b/dist/index.html index 12b599b..eafbbaa 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1 +1 @@ -NEU小站课程评分系统
\ No newline at end of file +NEU小站课程评分系统
\ No newline at end of file diff --git a/dist/js/app.f10e6fc3.js b/dist/js/app.926aef76.js similarity index 88% rename from dist/js/app.f10e6fc3.js rename to dist/js/app.926aef76.js index f5cdfd7..203a598 100644 --- a/dist/js/app.f10e6fc3.js +++ b/dist/js/app.926aef76.js @@ -1,2 +1,2 @@ -(function(){"use strict";var e={3292:function(e,t,s){var a=s(5130),o=s(6768);const n={key:0,class:"app-layout"},i={class:"main-content"},r={key:1,class:"forbidden-container"};function c(e,t,s,a,c,l){const u=(0,o.g2)("NavBar"),d=(0,o.g2)("router-view");return(0,o.uX)(),(0,o.CE)("div",null,[c.isAuthorized?((0,o.uX)(),(0,o.CE)("div",n,[(0,o.bF)(u),(0,o.Lk)("main",i,[(0,o.bF)(d)])])):((0,o.uX)(),(0,o.CE)("div",r,t[0]||(t[0]=[(0,o.Fv)('

您的访问被拒绝

只有在 NEU小站 完成 校园网或校园邮箱验证 的用户才能访问课程评分系统。

请确保您已完成相关操作,然后重新尝试访问。

',4)])))])}s(4114);var l=s(4232);const u={class:"navbar"},d={class:"navbar-container"},h={class:"navbar-menu desktop-only"},m={class:"hamburger-box"},p={key:0,class:"mobile-menu-content"},g={class:"mobile-links"};function k(e,t,s,n,i,r){const c=(0,o.g2)("router-link");return(0,o.uX)(),(0,o.CE)("nav",u,[(0,o.Lk)("div",d,[(0,o.Lk)("div",{class:"navbar-brand",onClick:t[0]||(t[0]=t=>e.$router.push("/"))},t[3]||(t[3]=[(0,o.Lk)("img",{src:"https://download.xn--xhq44jb2fzpc.com/images/logo-hd.png",alt:"NEU小站",class:"logo"},null,-1),(0,o.Lk)("span",{class:"brand-text"},"课程评分",-1),(0,o.Lk)("span",{class:"version-badge"},"V2",-1)])),(0,o.Lk)("div",h,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.menuItems,(e=>((0,o.uX)(),(0,o.Wv)(c,{key:e.name,to:e.path,class:"nav-item","active-class":"active"},{default:(0,o.k6)((()=>[(0,o.eW)((0,l.v_)(e.label),1)])),_:2},1032,["to"])))),128))]),(0,o.Lk)("button",{class:"navbar-toggle mobile-only",onClick:t[1]||(t[1]=(...e)=>r.toggleMenu&&r.toggleMenu(...e)),"aria-label":"Toggle navigation"},[(0,o.Lk)("span",m,[(0,o.Lk)("span",{class:(0,l.C4)(["hamburger-inner",{"is-active":i.isMenuOpen}])},null,2)])])]),(0,o.bF)(a.eB,{name:"fade"},{default:(0,o.k6)((()=>[i.isMenuOpen?((0,o.uX)(),(0,o.CE)("div",{key:0,class:"mobile-menu-overlay",onClick:t[2]||(t[2]=(...e)=>r.closeMenu&&r.closeMenu(...e))})):(0,o.Q3)("",!0)])),_:1}),(0,o.bF)(a.eB,{name:"slide-down"},{default:(0,o.k6)((()=>[i.isMenuOpen?((0,o.uX)(),(0,o.CE)("div",p,[t[4]||(t[4]=(0,o.Lk)("div",{class:"mobile-menu-header"},[(0,o.Lk)("span",{class:"mobile-menu-title"},"菜单")],-1)),(0,o.Lk)("div",g,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.menuItems,(e=>((0,o.uX)(),(0,o.Wv)(c,{key:e.name,to:e.path,class:"mobile-nav-item","active-class":"active",onClick:r.closeMenu},{default:(0,o.k6)((()=>[(0,o.eW)((0,l.v_)(e.label),1)])),_:2},1032,["to","onClick"])))),128))]),t[5]||(t[5]=(0,o.Lk)("div",{class:"mobile-footer"},[(0,o.eW)(" © 2025 "),(0,o.Lk)("a",{href:"https://www.xn--xhq44jb2fzpc.com",target:"_blank",style:{color:"inherit","text-decoration":"none"}},"NEU小站")],-1))])):(0,o.Q3)("",!0)])),_:1})])}var v={name:"NavBar",data(){return{isMenuOpen:!1,menuItems:[{label:"使用必看",path:"/",name:"home"},{label:"选修课评分",path:"/rating",name:"rating"},{label:"必修课评分",path:"/ratingforcomp",name:"ratingforcomp"},{label:"我的课程",path:"/courses",name:"course-list"},{label:"关于",path:"/about",name:"about"}]}},methods:{toggleMenu(){this.isMenuOpen=!this.isMenuOpen},closeMenu(){this.isMenuOpen=!1}}},C=s(1241);const b=(0,C.A)(v,[["render",k],["__scopeId","data-v-2d6400c2"]]);var y=b,f={name:"App",data(){return{isAuthorized:!1,authChecked:!1}},components:{NavBar:y},mounted(){this.checkLoginStatus()},methods:{async checkLoginStatus(){const e=document.cookie.split("; ").reduce(((e,t)=>{const[s,a]=t.split("=");return s&&a&&(e[s.trim()]=decodeURIComponent(a)),e}),{}).token;if(e)try{const t=await fetch("https://newfront.xn--xhq44jb2fzpc.com/user/info",{method:"GET",headers:{Authorization:e}}),s=await t.json();t.ok&&!0===s.activated?this.isAuthorized=!0:console.warn("用户未通过验证:用户未激活")}catch(t){console.error("获取用户信息失败:",t)}finally{this.authChecked=!0}}}};const L=(0,C.A)(f,[["render",c]]);var w=L,_=s(6762),S=(s(4188),s(973));const E={key:0},x={id:"homepage-title"},P={key:1};function M(e,t,s,a,n,i){const r=(0,o.g2)("router-link");return n.isLoaded?((0,o.uX)(),(0,o.CE)("div",E,[(0,o.Lk)("div",null,[(0,o.Lk)("h2",x,(0,l.v_)(n.greeting)+", "+(0,l.v_)(n.nickname)+"!",1),t[9]||(t[9]=(0,o.Fv)("

欢迎您使用NEU小站课程评分系统!

本系统采用全匿名方式,学生可以匿名对课程进行评分和发表评论。每人对每个课程只能评分一次,若需要多次评分,系统将记录用户最后一次提交的评分结果。为保护隐私,发表评论时不会显示用户在NEU小站的用户名,每次评论的昵称均由用户自行定义。

本系统中,课程分为两大类:选修课和必修课。选修课有8个小类:通识选修、人文选修、专业方向、体育、学科基础、暑期国际课、数学与自然科学、重修专栏。人文选修类包括采用“抢选”方式进行选课的所有选修课,以及“改革开放史”和“社会主义发展史”两门人文社会科学类的选修课。体育课单独作为一类,不属于人文选修类。重修课程的选课归为选修课的“重修专栏”类别,不属于必修课范畴。重修专栏可以分享任何类别课程,但仅限分享重修体验

必修课有5个小类:数学与自然科学、人文社会科学、学科基础、专业方向、实践。如上所述,本系统中重修的必修课程也属于选修课范畴。特别说明:军训课程属于实践类,系辅导员给分,在创建课程时课程教师请填写辅导员。

",4)),(0,o.Lk)("p",null,[t[1]||(t[1]=(0,o.eW)(" 在创建课程时,请先了解课程的类别,以及课程的")),t[2]||(t[2]=(0,o.Lk)("strong",null,"开课院系",-1)),t[3]||(t[3]=(0,o.eW)(",")),(0,o.bF)(r,{to:"/courses?m=true",class:"guide-link"},{default:(0,o.k6)((()=>t[0]||(t[0]=[(0,o.eW)("点击此处")]))),_:1}),t[4]||(t[4]=(0,o.eW)("查看指引。")),t[5]||(t[5]=(0,o.Lk)("strong",null,'如果同一课程的任课教师不同,用户可以创建多个同名课程,例如"A老师-篮球"和"B老师-篮球"将被视为两个不同的课程。',-1)),t[6]||(t[6]=(0,o.eW)("创建的课程卡片")),t[7]||(t[7]=(0,o.Lk)("strong",null,"需经过管理员审核",-1)),t[8]||(t[8]=(0,o.eW)(',审核进度可在"我的课程"中实时查看。 '))]),t[10]||(t[10]=(0,o.Lk)("p",null,[(0,o.eW)(" 本系统鼓励同学们提供真实、有价值的评分。"),(0,o.Lk)("strong",null,"禁止发布带有侮辱性的人身攻击等恶意评论。"),(0,o.eW)("管理员将对恶意用户进行封禁处理,确保评分系统的文明环境。 ")],-1))])])):((0,o.uX)(),(0,o.CE)("div",P,t[11]||(t[11]=[(0,o.Lk)("p",null,"加载中,请稍后...",-1)])))}var T={data(){return{name:"Homepage",greeting:"",nickname:"",isLoaded:!1}},mounted(){this.setGreeting(),this.fetchNickname(),setTimeout((()=>{this.isLoaded=!0}),300)},methods:{setGreeting(){const e=(new Date).getHours();this.greeting=e<12?"早上好":e<14?"中午好":e<18?"下午好":"晚上好"},async fetchNickname(){const e=document.cookie.split("; ").reduce(((e,t)=>{const[s,a]=t.split("=");return e[s]=decodeURIComponent(a),e}),{}).token;if(e)try{const t=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/avatar/nickname",{method:"GET",headers:{Authorization:e}});if(!t.ok){const e=await t.json();return void console.error("获取昵称失败:",e.message||"未知错误")}const s=await t.json();s.nickname?(this.nickname=s.nickname,console.log("Nickname successfully fetched:",s.nickname)):(this.nickname="默认昵称",console.log("Nickname field is missing. Using default nickname."))}catch(t){console.error("获取昵称时出错:",t)}else console.error("未找到JWT信息")}}};const I=(0,C.A)(T,[["render",M],["__scopeId","data-v-b5d4cca8"]]);var X=I;const j={class:"course-list-page"},$={key:0,class:"loading-message"},F={key:1,class:"empty-message"},N={key:2,class:"course-cards"},A=["onClick"],z={class:"card-header"},W={class:"course-name-title"},U={class:"card-body"},O={class:"info-row"},V={class:"info-val"},R={class:"info-row"},D={class:"info-val truncate"},q={class:"info-row"},B={class:"info-val truncate"},Q={class:"card-footer"},J={class:"time-info"},K={class:"time-row"},H={class:"time-val"},G={class:"time-row"},Y={class:"time-val"},Z={key:3,class:"pagination-bar"},ee=["disabled"],te=["onClick"],se=["disabled"],ae={class:"add-course-section card-style"},oe={class:"section-header"},ne={class:"input-grid"},ie={class:"input-group"},re={class:"input-group"},ce={class:"input-group"},le=["value"],ue={class:"input-group"},de={class:"button-group"},he={key:4,class:"help-modal"},me={class:"help-modal-content"},pe={class:"help-modal-header"};function ge(e,t,s,n,i,r){return(0,o.uX)(),(0,o.CE)("div",j,[t[24]||(t[24]=(0,o.Lk)("h2",{class:"page-title"},"我添加的课程",-1)),i.isLoaded?0===i.submissions.length?((0,o.uX)(),(0,o.CE)("div",F," 您还没有添加任何课程。 ")):((0,o.uX)(),(0,o.CE)("div",N,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.paginatedSubmissions,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.submit_id,class:"course-card",onClick:t=>r.handleCardClick(e)},[(0,o.Lk)("div",z,[(0,o.Lk)("h3",W,(0,l.v_)(e.course_name),1),(0,o.Lk)("div",{class:(0,l.C4)(["status-tag",r.getStatusClass(e.status)])},(0,l.v_)(e.status),3)]),(0,o.Lk)("div",U,[(0,o.Lk)("div",O,[t[9]||(t[9]=(0,o.Lk)("span",{class:"info-label"},"分类",-1)),(0,o.Lk)("span",V,(0,l.v_)(r.getCategoryName(e.category_id)),1)]),(0,o.Lk)("div",R,[t[10]||(t[10]=(0,o.Lk)("span",{class:"info-label"},"教师",-1)),(0,o.Lk)("span",D,(0,l.v_)(e.teachers),1)]),(0,o.Lk)("div",q,[t[11]||(t[11]=(0,o.Lk)("span",{class:"info-label"},"院系",-1)),(0,o.Lk)("span",B,(0,l.v_)(r.getCollegeName(e.college)),1)])]),(0,o.Lk)("div",Q,[(0,o.Lk)("div",J,[(0,o.Lk)("div",K,[t[12]||(t[12]=(0,o.Lk)("span",{class:"time-label"},"提交:",-1)),(0,o.Lk)("span",H,(0,l.v_)(r.formatTimeShort(e.create_time)),1)]),(0,o.Lk)("div",G,[t[13]||(t[13]=(0,o.Lk)("span",{class:"time-label"},"更新:",-1)),(0,o.Lk)("span",Y,(0,l.v_)(r.formatTimeShort(e.status_update_time)),1)])])])],8,A)))),128))])):((0,o.uX)(),(0,o.CE)("div",$," 加载中,请稍后... ")),i.totalPages>1?((0,o.uX)(),(0,o.CE)("div",Z,[(0,o.Lk)("button",{onClick:t[0]||(t[0]=e=>r.goToPage(1)),class:(0,l.C4)({active:1===i.currentPage}),disabled:1===i.currentPage},"首页",10,ee),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.getPaginationPages(),(e=>((0,o.uX)(),(0,o.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,l.C4)({active:i.currentPage===e})},(0,l.v_)(e),11,te)))),128)),(0,o.Lk)("button",{onClick:t[1]||(t[1]=e=>r.goToPage(i.totalPages)),class:(0,l.C4)({active:i.currentPage===i.totalPages}),disabled:i.currentPage===i.totalPages}," 尾页 ",10,se)])):(0,o.Q3)("",!0),(0,o.Lk)("div",ae,[(0,o.Lk)("div",oe,[t[15]||(t[15]=(0,o.Lk)("h2",null,"我要添加课程",-1)),(0,o.Lk)("button",{class:"help-btn",onClick:t[2]||(t[2]=e=>i.showHelp=!0)},t[14]||(t[14]=[(0,o.Lk)("span",{class:"help-icon"},"?",-1),(0,o.eW)(" 帮助 ")]))]),(0,o.Lk)("div",ne,[(0,o.Lk)("div",ie,[t[16]||(t[16]=(0,o.Lk)("label",null,"课程名称",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.newCourseName=e),type:"text",placeholder:"请输入课程名称",class:"modern-input"},null,512),[[a.Jo,i.newCourseName]])]),(0,o.Lk)("div",re,[t[18]||(t[18]=(0,o.Lk)("label",null,"课程类别",-1)),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.newCategoryId=e),class:"modern-select"},t[17]||(t[17]=[(0,o.Fv)('',14)]),512),[[a.u1,i.newCategoryId]])]),(0,o.Lk)("div",ce,[t[20]||(t[20]=(0,o.Lk)("label",null,"开课院系",-1)),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[5]||(t[5]=e=>i.newCollege=e),class:"modern-select"},[t[19]||(t[19]=(0,o.Lk)("option",{value:"",disabled:""},"请选择开课院系",-1)),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.filteredColleges,((e,t)=>((0,o.uX)(),(0,o.CE)("option",{key:t,value:t},(0,l.v_)(e),9,le)))),128))],512),[[a.u1,i.newCollege]])]),(0,o.Lk)("div",ue,[t[21]||(t[21]=(0,o.Lk)("label",null,"任课教师",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[6]||(t[6]=e=>i.newTeachers=e),type:"text",placeholder:"多个教师用英文逗号隔开,如A,B",class:"modern-input"},null,512),[[a.Jo,i.newTeachers]])]),(0,o.Lk)("div",de,[(0,o.Lk)("button",{onClick:t[7]||(t[7]=(...e)=>r.submitCourse&&r.submitCourse(...e)),class:"submit-btn"},"提交课程")])])]),i.showHelp?((0,o.uX)(),(0,o.CE)("div",he,[(0,o.Lk)("div",me,[(0,o.Lk)("div",pe,[t[22]||(t[22]=(0,o.Lk)("h3",null,"关于本系统课程信息的说明",-1)),(0,o.Lk)("button",{class:"close-btn",onClick:t[8]||(t[8]=e=>i.showHelp=!1)},"×")]),t[23]||(t[23]=(0,o.Fv)('

一些说明

本系统中,课程分为两大类:选修课和必修课。选修课有8个小类:通识选修、人文选修、专业方向、体育、学科基础、暑期国际课、数学与自然科学、重修专栏。人文选修类包括采用“抢选”方式进行选课的所有选修课,以及“改革开放史”和“社会主义发展史”两门人文社会科学类的选修课。体育课单独作为一类,不属于人文选修类。重修课程的选课归为选修课的“重修专栏”类别,不属于必修课范畴。重修专栏可以分享任何类别课程,但仅限分享重修体验

必修课有5个小类:数学与自然科学、人文社会科学、学科基础、专业方向、实践。如上所述,本系统中重修的必修课程也属于选修课范畴。特别说明:军训课程属于实践类,系辅导员给分,在创建课程时课程教师请填写辅导员。

在创建课程时,请先了解课程的类别,以及课程的开课院系(详见下文)如果同一课程的任课教师不同,用户可以创建多个同名课程,例如“A老师-篮球”和“B老师-篮球”将被视为两个不同的课程。创建的课程卡片需经过管理员审核,审核进度可在“我的课程”中实时查看。

如何查看课程类别和开课院系?

1. 本人课程

在教务系统选择“我的考试”,选择对应的学期后,即可查看当前学期的课程类别和开课院系。

2. 非本人课程

在教务系统选择“公共课表查询”,课表类型选择“班级课表”,再选好要查询的学期,并填写要查询的班级名称,点击查询按钮。

进入班级课表后,即可对应课程的开课院系。然后记下老师的姓名。

然后回到公共课表查询页面,课表类型选择“教师课表”,同样选好要查询的学期,并填写要查询的教师姓名,点击查询按钮。

进入教师课表后,找到此课程,即可查看课程类别。

',1))])])):(0,o.Q3)("",!0)])}s(4979);var ke={components:{},data(){return{submissions:[],newCourseName:"",newCategoryId:"",newTeachers:"",newCollege:"",currentPage:1,itemsPerPage:10,totalPages:1,isLoaded:!1,cachedEmail:null,showHelp:!1,maxVisiblePages:10,collegeMap:{59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"}}},computed:{paginatedSubmissions(){const e=(this.currentPage-1)*this.itemsPerPage,t=e+this.itemsPerPage;return this.submissions.slice(e,t)},filteredColleges(){return Object.fromEntries(Object.entries(this.collegeMap).filter((([e])=>"59"!==e)))}},mounted(){this.checkMobile(),window.addEventListener("resize",this.checkMobile),setTimeout((async()=>{this.isLoaded=!0,this.fetchSubmissions()}),300),"true"===this.$route.query.m&&(this.showHelp=!0);const e=this.$route.query.c;if(e)try{const t=atob(e);this.isPositiveInteger(t)&&this.$router.push(`/detail/${t}`)}catch(t){}},beforeUnmount(){window.removeEventListener("resize",this.checkMobile)},methods:{checkMobile(){this.maxVisiblePages=window.innerWidth<=768?5:10},isPositiveInteger(e){const t=Number(e);return Number.isInteger(t)&&t>0},async fetchSubmissions(){const e=this.getCookie("token");if(e)try{const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/user/user-submissions",{method:"GET",headers:{"Content-Type":"application/json",Authorization:e}});if(200!==t.status){const e=await t.json();return void alert(e.error||"查询投稿记录失败")}const s=await t.json();this.submissions=s,this.totalPages=Math.ceil(this.submissions.length/this.itemsPerPage)}catch(t){console.error("Fetch submissions error",t)}},getCookie(e){const t=document.cookie.split(";");for(let s of t){const[t,a]=s.trim().split("=");if(t===e)return a}return null},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e)},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,a=this.maxVisiblePages;if(t<=a)for(let o=1;o<=t;o++)e.push(o);else{let o=s-Math.floor(a/2);o=Math.max(o,1);let n=o+a-1;n>t&&(n=t,o=Math.max(n-a+1,1));for(let t=o;t<=n;t++)e.push(t)}return e},async submitCourse(){if(this.newCourseName&&this.newCategoryId&&this.newTeachers&&this.newCollege){if(confirm("确认提交审核吗?")){const e=this.getCookie("token");if(!e)return void alert("无法获取JWT,请重新登录。");const t={course_name:this.newCourseName,category_id:this.newCategoryId,teachers:this.newTeachers,college:this.newCollege};await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/user/submit-course",{method:"POST",headers:{"Content-Type":"application/json",Authorization:e},body:JSON.stringify(t)}),this.newCourseName="",this.newCategoryId="",this.newTeachers="",this.newCollege="",this.fetchSubmissions()}}else alert("请填写所有字段后提交!")},getCategoryName(e){const t={1:"通识选修类",2:"人文选修类",3:"专业方向类",4:"体育类",5:"学科基础类",6:"暑期国际课",7:"数学与自然科学类",8:"重修专栏",9:"必修-数理",10:"必修-人文",11:"必修-学科",12:"必修-专业",13:"必修-实践"};return t[e]||"未知分类"},formatTime(e){const t=new Date(e),s=t.getFullYear(),a=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${a}-${o} ${n}:${i}`},formatTimeShort(e){if(!e)return"-";const t=new Date(e),s=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0");return`${s}-${a}`},handleCardClick(e){0!==e.course_id&&this.$router.push(`/detail/${e.course_id}`)},getStatusClass(e){return"已通过"===e?"status-approved":"待审核"===e?"status-pending":"已拒绝"===e?"status-rejected":""},getCollegeName(e){return this.collegeMap[e]||"未知院系"}}};const ve=(0,C.A)(ke,[["render",ge],["__scopeId","data-v-2964ca48"]]);var Ce=ve;const be={key:0,class:"rating-page"},ye={class:"search-sort-bar card-style"},fe={class:"search-inputs"},Le={class:"input-wrapper"},we={class:"input-wrapper teacher-input"},_e={class:"filters-row"},Se={class:"category-checkboxes"},Ee=["value"],xe={class:"actions-row"},Pe={class:"select-group"},Me=["value"],Te={class:"course-cards"},Ie=["onClick"],Xe={class:"card-header"},je={class:"course-name-title"},$e={key:0,class:"course-tags"},Fe={class:"card-body"},Ne={class:"info-row"},Ae={class:"info-val"},ze={class:"info-row"},We={class:"info-val truncate"},Ue={class:"info-row"},Oe={class:"info-val truncate"},Ve={class:"card-footer"},Re={class:"rating-info"},De={class:"score"},qe={class:"count"},Be={key:0,class:"top-comment"},Qe={key:1,class:"top-comment placeholder"},Je={class:"pagination-bar"},Ke=["onClick"],He=["disabled"],Ge={key:1};function Ye(e,t,s,n,i,r){return i.isLoaded?((0,o.uX)(),(0,o.CE)("div",be,[t[17]||(t[17]=(0,o.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,o.Lk)("div",ye,[(0,o.Lk)("div",fe,[(0,o.Lk)("div",Le,[t[8]||(t[8]=(0,o.Lk)("span",{class:"search-icon"},"🔍",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"搜索课程...",class:"modern-input"},null,512),[[a.Jo,i.searchQuery]])]),(0,o.Lk)("div",we,[t[9]||(t[9]=(0,o.Lk)("span",{class:"search-icon"},"👨‍🏫",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",placeholder:"搜索教师 (如: 张三,李四)",class:"modern-input"},null,512),[[a.Jo,i.teacherQuery]])])]),(0,o.Lk)("div",_e,[(0,o.Lk)("div",Se,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.categories,(e=>((0,o.uX)(),(0,o.CE)("label",{key:e.value,class:"checkbox-label"},[(0,o.bo)((0,o.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:e.value},null,8,Ee),[[a.lH,i.selectedCategories]]),t[10]||(t[10]=(0,o.Lk)("span",{class:"checkmark"},null,-1)),(0,o.eW)(" "+(0,l.v_)(e.label),1)])))),128))])]),(0,o.Lk)("div",xe,[(0,o.Lk)("div",Pe,[(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.sortBy=e),class:"modern-select"},t[11]||(t[11]=[(0,o.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,o.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,o.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[a.u1,i.sortBy]]),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCollege=e),class:"modern-select"},[t[12]||(t[12]=(0,o.Lk)("option",{value:""},"全部院系",-1)),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.filteredColleges,(([e,t])=>((0,o.uX)(),(0,o.CE)("option",{key:e,value:e},(0,l.v_)(t),9,Me)))),128))],512),[[a.u1,i.selectedCollege]])]),(0,o.Lk)("button",{onClick:t[5]||(t[5]=(...e)=>r.searchCourses&&r.searchCourses(...e)),class:"search-btn"}," 更新查询 ")])]),(0,o.Lk)("div",Te,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.courses,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>r.showCourseDetail(e)},[(0,o.Lk)("div",Xe,[(0,o.Lk)("h3",je,(0,l.v_)(e.course_name),1),e.titles&&e.titles.length>0?((0,o.uX)(),(0,o.CE)("div",$e,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(e.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"mini-tag",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128))])):(0,o.Q3)("",!0)]),(0,o.Lk)("div",Fe,[(0,o.Lk)("div",Ne,[t[13]||(t[13]=(0,o.Lk)("span",{class:"info-label"},"分类",-1)),(0,o.Lk)("span",Ae,(0,l.v_)(r.getCategoryName(e.category_id)),1)]),(0,o.Lk)("div",ze,[t[14]||(t[14]=(0,o.Lk)("span",{class:"info-label"},"教师",-1)),(0,o.Lk)("span",We,(0,l.v_)(e.teachers),1)]),(0,o.Lk)("div",Ue,[t[15]||(t[15]=(0,o.Lk)("span",{class:"info-label"},"院系",-1)),(0,o.Lk)("span",Oe,(0,l.v_)(r.getCollegeName(e.college)),1)])]),(0,o.Lk)("div",Ve,[(0,o.Lk)("div",Re,[(0,o.Lk)("span",De,(0,l.v_)(e.rating),1),t[16]||(t[16]=(0,o.Lk)("span",{class:"score-label"},"分",-1)),(0,o.Lk)("span",qe,"("+(0,l.v_)(e.rating_count)+"人)",1)]),e.top_comment?((0,o.uX)(),(0,o.CE)("div",Be,' "'+(0,l.v_)(r.formatTopComment(e.top_comment))+'" ',1)):((0,o.uX)(),(0,o.CE)("div",Qe," 暂无评论 "))])],8,Ie)))),128))]),(0,o.Lk)("div",Je,[(0,o.Lk)("button",{onClick:t[6]||(t[6]=e=>r.goToPage(1)),class:(0,l.C4)({active:1===i.currentPage})},"首页",2),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.getPaginationPages(),(e=>((0,o.uX)(),(0,o.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,l.C4)({active:i.currentPage===e})},(0,l.v_)(e),11,Ke)))),128)),(0,o.Lk)("button",{onClick:t[7]||(t[7]=e=>r.goToPage(i.totalPages)),class:(0,l.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,He)])])):((0,o.uX)(),(0,o.CE)("div",Ge,t[18]||(t[18]=[(0,o.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var Ze={data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],categories:[{label:"通识选修类",value:"1"},{label:"人文选修类",value:"2"},{label:"专业方向类",value:"3"},{label:"体育类",value:"4"},{label:"学科基础类",value:"5"},{label:"暑期国际课",value:"6"},{label:"数学与自然科学类",value:"7"},{label:"重修专栏",value:"8"}],maxVisiblePages:10,collegeMap:{59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"}}},computed:{filteredColleges(){return Object.entries(this.collegeMap).filter((([e])=>"59"!==e))}},mounted(){this.checkMobile(),window.addEventListener("resize",this.checkMobile),setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},beforeUnmount(){window.removeEventListener("resize",this.checkMobile)},methods:{checkMobile(){this.maxVisiblePages=window.innerWidth<=768?5:10},async fetchCourses(){let e="rating-asc"===this.sortBy?"rating":this.sortBy;this.sortOrder="rating-asc"===this.sortBy?"asc":"desc";const t=0===this.selectedCategories.length?"1,2,3,4,5,6,7,8":this.selectedCategories.join(","),s=this.selectedCollege?`&college=${this.selectedCollege}`:"",a=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${a}&teacher=${o}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i.courses,this.currentPage=i.currentPage,this.totalPages=i.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,a=this.maxVisiblePages;if(t<=a)for(let o=1;o<=t;o++)e.push(o);else{let o=s-Math.floor(a/2);o=Math.max(o,1);let n=o+a-1;n>t&&(n=t,o=Math.max(n-a+1,1));for(let t=o;t<=n;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){window.open(`/detail/${e.course_id}`,"_blank")},formatTopComment(e){if(!e)return"";let t=0,s="";for(let a=0;a255?1:.5;if(t+o>29)return s+"...";t+=o,s+=e[a]}return s},getCategoryName(e){const t={1:"通识选修类",2:"人文选修类",3:"专业方向类",4:"体育类",5:"学科基础类",6:"暑期国际课",7:"数学与自然科学类",8:"重修专栏"};return t[e]||"未知分类"},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"}}};const et=(0,C.A)(Ze,[["render",Ye],["__scopeId","data-v-7d8ad36d"]]);var tt=et;const st={key:0,class:"rating-page"},at={class:"search-sort-bar card-style"},ot={class:"search-inputs"},nt={class:"input-wrapper"},it={class:"input-wrapper teacher-input"},rt={class:"filters-row"},ct={class:"category-checkboxes"},lt=["value"],ut={class:"actions-row"},dt={class:"select-group"},ht=["value"],mt={class:"course-cards"},pt=["onClick"],gt={class:"card-header"},kt={class:"course-name-title"},vt={key:0,class:"course-tags"},Ct={class:"card-body"},bt={class:"info-row"},yt={class:"info-val"},ft={class:"info-row"},Lt={class:"info-val truncate"},wt={class:"info-row"},_t={class:"info-val truncate"},St={class:"card-footer"},Et={class:"rating-info"},xt={class:"score"},Pt={class:"count"},Mt={key:0,class:"top-comment"},Tt={key:1,class:"top-comment placeholder"},It={class:"pagination-bar"},Xt=["onClick"],jt=["disabled"],$t={key:1};function Ft(e,t,s,n,i,r){return i.isLoaded?((0,o.uX)(),(0,o.CE)("div",st,[t[17]||(t[17]=(0,o.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,o.Lk)("div",at,[(0,o.Lk)("div",ot,[(0,o.Lk)("div",nt,[t[8]||(t[8]=(0,o.Lk)("span",{class:"search-icon"},"🔍",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"搜索课程...",class:"modern-input"},null,512),[[a.Jo,i.searchQuery]])]),(0,o.Lk)("div",it,[t[9]||(t[9]=(0,o.Lk)("span",{class:"search-icon"},"👨‍🏫",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",placeholder:"搜索教师 (如: 张三,李四)",class:"modern-input"},null,512),[[a.Jo,i.teacherQuery]])])]),(0,o.Lk)("div",rt,[(0,o.Lk)("div",ct,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.categories,(e=>((0,o.uX)(),(0,o.CE)("label",{key:e.value,class:"checkbox-label"},[(0,o.bo)((0,o.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:e.value},null,8,lt),[[a.lH,i.selectedCategories]]),t[10]||(t[10]=(0,o.Lk)("span",{class:"checkmark"},null,-1)),(0,o.eW)(" "+(0,l.v_)(e.label),1)])))),128))])]),(0,o.Lk)("div",ut,[(0,o.Lk)("div",dt,[(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.sortBy=e),class:"modern-select"},t[11]||(t[11]=[(0,o.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,o.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,o.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[a.u1,i.sortBy]]),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCollege=e),class:"modern-select"},[t[12]||(t[12]=(0,o.Lk)("option",{value:""},"全部院系",-1)),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.filteredColleges,(([e,t])=>((0,o.uX)(),(0,o.CE)("option",{key:e,value:e},(0,l.v_)(t),9,ht)))),128))],512),[[a.u1,i.selectedCollege]])]),(0,o.Lk)("button",{onClick:t[5]||(t[5]=(...e)=>r.searchCourses&&r.searchCourses(...e)),class:"search-btn"}," 更新查询 ")])]),(0,o.Lk)("div",mt,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.courses,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>r.showCourseDetail(e)},[(0,o.Lk)("div",gt,[(0,o.Lk)("h3",kt,(0,l.v_)(e.course_name),1),e.titles&&e.titles.length>0?((0,o.uX)(),(0,o.CE)("div",vt,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(e.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"mini-tag",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128))])):(0,o.Q3)("",!0)]),(0,o.Lk)("div",Ct,[(0,o.Lk)("div",bt,[t[13]||(t[13]=(0,o.Lk)("span",{class:"info-label"},"分类",-1)),(0,o.Lk)("span",yt,(0,l.v_)(r.getCategoryName(e.category_id)),1)]),(0,o.Lk)("div",ft,[t[14]||(t[14]=(0,o.Lk)("span",{class:"info-label"},"教师",-1)),(0,o.Lk)("span",Lt,(0,l.v_)(e.teachers),1)]),(0,o.Lk)("div",wt,[t[15]||(t[15]=(0,o.Lk)("span",{class:"info-label"},"院系",-1)),(0,o.Lk)("span",_t,(0,l.v_)(r.getCollegeName(e.college)),1)])]),(0,o.Lk)("div",St,[(0,o.Lk)("div",Et,[(0,o.Lk)("span",xt,(0,l.v_)(e.rating),1),t[16]||(t[16]=(0,o.Lk)("span",{class:"score-label"},"分",-1)),(0,o.Lk)("span",Pt,"("+(0,l.v_)(e.rating_count)+"人)",1)]),e.top_comment?((0,o.uX)(),(0,o.CE)("div",Mt,' "'+(0,l.v_)(r.formatTopComment(e.top_comment))+'" ',1)):((0,o.uX)(),(0,o.CE)("div",Tt," 暂无评论 "))])],8,pt)))),128))]),(0,o.Lk)("div",It,[(0,o.Lk)("button",{onClick:t[6]||(t[6]=e=>r.goToPage(1)),class:(0,l.C4)({active:1===i.currentPage})},"首页",2),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.getPaginationPages(),(e=>((0,o.uX)(),(0,o.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,l.C4)({active:i.currentPage===e})},(0,l.v_)(e),11,Xt)))),128)),(0,o.Lk)("button",{onClick:t[7]||(t[7]=e=>r.goToPage(i.totalPages)),class:(0,l.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,jt)])])):((0,o.uX)(),(0,o.CE)("div",$t,t[18]||(t[18]=[(0,o.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var Nt={data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],categories:[{label:"数学与自然科学类",value:"9"},{label:"人文社会科学类",value:"10"},{label:"学科基础类",value:"11"},{label:"专业方向类",value:"12"},{label:"实践类",value:"13"}],maxVisiblePages:10,collegeMap:{59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"}}},computed:{filteredColleges(){return Object.entries(this.collegeMap).filter((([e])=>"59"!==e))}},mounted(){this.checkMobile(),window.addEventListener("resize",this.checkMobile),setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},beforeUnmount(){window.removeEventListener("resize",this.checkMobile)},methods:{checkMobile(){this.maxVisiblePages=window.innerWidth<=768?5:10},async fetchCourses(){let e="rating-asc"===this.sortBy?"rating":this.sortBy;this.sortOrder="rating-asc"===this.sortBy?"asc":"desc";const t=0===this.selectedCategories.length?"9,10,11,12,13":this.selectedCategories.join(","),s=this.selectedCollege?`&college=${this.selectedCollege}`:"",a=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${a}&teacher=${o}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i.courses,this.currentPage=i.currentPage,this.totalPages=i.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,a=this.maxVisiblePages;if(t<=a)for(let o=1;o<=t;o++)e.push(o);else{let o=s-Math.floor(a/2);o=Math.max(o,1);let n=o+a-1;n>t&&(n=t,o=Math.max(n-a+1,1));for(let t=o;t<=n;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){this.$router.push(`/detail/${e.course_id}`)},formatTopComment(e){if(!e)return"";let t=0,s="";for(let a=0;a255?1:.5;if(t+o>29)return s+"...";t+=o,s+=e[a]}return s},getCategoryName(e){const t={9:"数学与自然科学类",10:"人文社会科学类",11:"学科基础类",12:"专业方向类",13:"实践类"};return t[e]||"未知分类"},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"}}};const At=(0,C.A)(Nt,[["render",Ft],["__scopeId","data-v-3228e625"]]);var zt=At;const Wt={class:"sidebar"},Ut={class:"header"},Ot={class:"status-text"},Vt={key:0,class:"no-conversations"},Rt=["onClick"],Dt={class:"conversation-name"},qt={key:0,class:"new-message-label"},Bt={class:"conversation-updated-at"},Qt={class:"conversation-last-message"},Jt={class:"chat-container"},Kt={class:"conversation-info"},Ht={class:"message-bubble"},Gt={key:0},Yt={class:"input-container"};function Zt(e,t,s,a,n,i){const r=(0,o.g2)("el-scrollbar"),c=(0,o.g2)("el-button"),u=(0,o.g2)("el-input"),d=(0,o.g2)("el-tooltip"),h=(0,o.g2)("CourseDetailModal");return(0,o.uX)(),(0,o.CE)("div",{class:(0,l.C4)(["chat-page",{"mobile-chat-active":n.activeConversation}])},[(0,o.Lk)("div",Wt,[(0,o.Lk)("h3",Ut,[t[3]||(t[3]=(0,o.eW)(" 会话列表 ")),(0,o.Lk)("span",{class:(0,l.C4)(["connection-status",{connected:n.isConnected,disconnected:!n.isConnected}])},[(0,o.Lk)("span",{class:(0,l.C4)(["status-indicator",{connected:n.isConnected,disconnected:!n.isConnected}])},null,2),(0,o.Lk)("span",Ot,(0,l.v_)(n.isConnected?"即时聊天已连接":"即时聊天已断开,正在重新连接..."),1)],2)]),(0,o.bF)(r,null,{default:(0,o.k6)((()=>[0===n.conversations.length?((0,o.uX)(),(0,o.CE)("div",Vt," 还没有会话,快去通过评论发起聊天吧! ")):((0,o.uX)(!0),(0,o.CE)(o.FK,{key:1},(0,o.pI)(n.conversations,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.conversation_id,class:(0,l.C4)(["conversation-item",e.conversation_id===n.activeConversation?"active":""]),onClick:t=>i.selectConversation(e.conversation_id)},[(0,o.Lk)("div",Dt,[(0,o.eW)((0,l.v_)(e.course_name)+" ",1),(0,o.Lk)("span",{class:(0,l.C4)(["role-label",{owner:"owner"===e.role,member:"member"===e.role}])},(0,l.v_)("owner"===e.role?"我发起的":"我收到的"),3),e.is_read?(0,o.Q3)("",!0):((0,o.uX)(),(0,o.CE)("span",qt,"新消息"))]),(0,o.Lk)("small",Bt,"更新时间: "+(0,l.v_)(i.formatDate(e.updated_at)),1),t[4]||(t[4]=(0,o.Lk)("br",null,null,-1)),(0,o.Lk)("small",Qt,(0,l.v_)(e.latest_sender?"我:":"对方:")+(0,l.v_)(e.content||"还没有消息哦,快去通过某条课程评论发起聊天吧!"),1)],10,Rt)))),128))])),_:1})]),(0,o.Lk)("div",Jt,[(0,o.Lk)("div",Kt,[(0,o.Lk)("button",{class:"mobile-back-btn",onClick:t[0]||(t[0]=e=>n.activeConversation=null)}," < 返回 "),(0,o.Lk)("span",null,(0,l.v_)(null!==n.rating?"该用户对课程评分为 "+n.rating.toFixed(1):"该用户暂未对课程进行评分"),1),(0,o.bF)(c,{onClick:t[1]||(t[1]=e=>n.selectedCourseId&&i.loadCourseDetail(n.selectedCourseId))},{default:(0,o.k6)((()=>t[5]||(t[5]=[(0,o.eW)("查看课程")]))),_:1})]),(0,o.bF)(r,{ref:"messageScrollbar",class:"message-list"},{default:(0,o.k6)((()=>[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(n.messages,((e,t)=>((0,o.uX)(),(0,o.CE)("div",{key:t,class:(0,l.C4)(["message",1===e.sender?"self":"other"])},[(0,o.Lk)("div",Ht,[(0,o.Lk)("span",null,(0,l.v_)(e.content),1),(0,o.Lk)("div",{class:(0,l.C4)(["message-info",1===e.sender?"align-right":"align-left"])},[(0,o.Lk)("small",null,(0,l.v_)(i.formatDate(e.created_at)),1),1===e.sender?((0,o.uX)(),(0,o.CE)("small",Gt,(0,l.v_)(e.is_read?"已读":"未读"),1)):(0,o.Q3)("",!0)],2)])],2)))),128))])),_:1},512),(0,o.Lk)("div",Yt,[(0,o.bF)(u,{modelValue:n.newMessage,"onUpdate:modelValue":t[2]||(t[2]=e=>n.newMessage=e),type:"textarea",rows:"2",placeholder:"请输入您的消息,按Enter换行,Ctrl+Enter发送。",class:"locked-input",onKeydown:i.handleKeyDown},null,8,["modelValue","onKeydown"]),(0,o.bF)(d,{content:"Ctrl + Enter",placement:"top"},{default:(0,o.k6)((()=>[(0,o.bF)(c,{onClick:i.sendMessage,type:"primary"},{default:(0,o.k6)((()=>t[6]||(t[6]=[(0,o.eW)("发送")]))),_:1},8,["onClick"])])),_:1})])]),n.selectedCourse?((0,o.uX)(),(0,o.Wv)(h,{key:0,isVisible:n.showDetail,course:n.selectedCourse,onClose:i.closeCourseDetail},null,8,["isVisible","course","onClose"])):(0,o.Q3)("",!0)],2)}var es=s(4373);const ts={key:0,class:"modal-overlay"},ss={class:"modal-content"},as={key:0,class:"loading"},os={key:1,class:"course-detail"},ns={key:0,class:"share-modal"},is={key:1,class:"error-modal"},rs={class:"rating-section"},cs={class:"total-rating"},ls={class:"progress-container"},us={class:"stars"},ds=["onMouseover","onClick"],hs={class:"ai-summary"},ms={key:0,class:"typing-cursor"},ps={class:"comment-section"},gs={class:"sort-options"},ks={key:0,class:"comments-list"},vs={class:"comment-meta"},Cs={class:"comment-time",style:{"margin-left":"10px"}},bs=["onClick"],ys={style:{"margin-top":"8px"}},fs={class:"comment-actions"},Ls={style:{color:"red"}},ws=["onClick"],_s=["onClick"],Ss={key:1,class:"no-comments"},Es={key:2,class:"chat-modal-overlay"},xs={class:"chat-modal-content"},Ps={class:"chat-modal-actions"},Ms=["disabled"],Ts={key:3,class:"chat-modal-overlay"},Is={class:"chat-modal-content"},Xs={class:"chat-modal-actions"},js={class:"new-comment"};function $s(e,t,s,n,i,r){const c=(0,o.g2)("el-progress");return s.isVisible?((0,o.uX)(),(0,o.CE)("div",ts,[(0,o.Lk)("div",ss,[(0,o.Lk)("span",{class:"close",onClick:t[0]||(t[0]=(...e)=>r.closeModal&&r.closeModal(...e))},"×"),i.loading?((0,o.uX)(),(0,o.CE)("div",as,t[16]||(t[16]=[(0,o.Lk)("p",null,"加载中...",-1)]))):(0,o.Q3)("",!0),!i.loading&&i.course&&i.course.course_id?((0,o.uX)(),(0,o.CE)("div",os,[(0,o.Lk)("h3",null,[(0,o.eW)((0,l.v_)(i.course.course_name)+" ",1),i.course.titles&&i.course.titles.length>0?((0,o.uX)(!0),(0,o.CE)(o.FK,{key:0},(0,o.pI)(i.course.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"course-title",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128)):(0,o.Q3)("",!0),(0,o.Lk)("button",{class:"share-btn",onClick:t[1]||(t[1]=(...e)=>r.shareCourse&&r.shareCourse(...e))},"分享给好友")]),(0,o.Lk)("p",null,[t[17]||(t[17]=(0,o.Lk)("strong",null,"分类:",-1)),(0,o.eW)(" "+(0,l.v_)(r.getCategoryName(i.course.category_id)),1)]),(0,o.Lk)("p",null,[t[18]||(t[18]=(0,o.Lk)("strong",null,"教师:",-1)),(0,o.eW)(" "+(0,l.v_)(i.course.teachers),1)]),(0,o.Lk)("p",null,[t[19]||(t[19]=(0,o.Lk)("strong",null,"开课院系:",-1)),(0,o.eW)(" "+(0,l.v_)(r.getCollegeName(i.course.college)),1)]),i.showShareModal?((0,o.uX)(),(0,o.CE)("div",ns," 链接复制成功,快去分享给其他小伙伴吧! ")):(0,o.Q3)("",!0),i.showErrorModal?((0,o.uX)(),(0,o.CE)("div",is," 获取评论数据失败,正在刷新页面... ")):(0,o.Q3)("",!0),(0,o.Lk)("div",rs,[(0,o.Lk)("h4",null,"课程实时平均分 ("+(0,l.v_)(i.course.rating_count)+"人评分)",1),(0,o.Lk)("div",cs,(0,l.v_)(i.totalRating),1),(0,o.Lk)("div",ls,[(0,o.bF)(c,{class:"progress",percentage:i.fiveStarPercent,status:"success","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("5星: "+(0,l.v_)(i.fiveStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.fourStarPercent,status:"success","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("4星: "+(0,l.v_)(i.fourStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.threeStarPercent,status:"warning","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("3星: "+(0,l.v_)(i.threeStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.twoStarPercent,status:"warning","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("2星: "+(0,l.v_)(i.twoStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.oneStarPercent,status:"exception","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("1星: "+(0,l.v_)(i.oneStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"])]),(0,o.Lk)("div",us,[((0,o.uX)(),(0,o.CE)(o.FK,null,(0,o.pI)(5,(e=>(0,o.Lk)("span",{key:e,class:(0,l.C4)({highlighted:e<=i.userRating}),onMouseover:t=>r.highlightStars(e),onMouseout:t[2]||(t[2]=(...e)=>r.resetStars&&r.resetStars(...e)),onClick:t=>r.confirmRating(e)}," ★ ",42,ds))),64))])]),(0,o.Lk)("p",hs,[t[20]||(t[20]=(0,o.Lk)("span",{style:{display:"block","margin-bottom":"-15px"}},[(0,o.Lk)("strong",null,"AI课程总结"),(0,o.Lk)("span",{style:{color:"white","font-size":"8px","margin-left":"5px","border-radius":"4px",padding:"1px 4px","background-color":"red","vertical-align":"super"}},"Beta"),(0,o.Lk)("span",{style:{"font-size":"12px","margin-left":"5px"}},[(0,o.eW)(" 内容由 "),(0,o.Lk)("img",{src:"https://download.东北大学.com/course_system/deepseek.svg",style:{height:"16px","vertical-align":"middle"}}),(0,o.eW)(" DeepSeek V3 生成,仅供参考 ")])],-1)),t[21]||(t[21]=(0,o.Lk)("br",null,null,-1)),i.displayedSummary?((0,o.uX)(),(0,o.CE)(o.FK,{key:0},[(0,o.eW)((0,l.v_)(i.displayedSummary),1),i.isTyping?((0,o.uX)(),(0,o.CE)("span",ms,"|")):(0,o.Q3)("",!0)],64)):((0,o.uX)(),(0,o.CE)(o.FK,{key:1},[(0,o.eW)(" 当前课程的评分和评论数据过少,暂不能生成AI总结。 ")],64))])])):(0,o.Q3)("",!0),(0,o.Lk)("div",ps,[(0,o.Lk)("div",gs,[(0,o.Lk)("label",null,[(0,o.bo)((0,o.Lk)("input",{type:"radio",value:"like_count","onUpdate:modelValue":t[3]||(t[3]=e=>i.sortBy=e),onChange:t[4]||(t[4]=(...e)=>r.fetchComments&&r.fetchComments(...e))},null,544),[[a.XL,i.sortBy]]),t[22]||(t[22]=(0,o.eW)(" 赞数最多优先"))]),(0,o.Lk)("label",null,[(0,o.bo)((0,o.Lk)("input",{type:"radio",value:"comment_time","onUpdate:modelValue":t[5]||(t[5]=e=>i.sortBy=e),onChange:t[6]||(t[6]=(...e)=>r.fetchComments&&r.fetchComments(...e))},null,544),[[a.XL,i.sortBy]]),t[23]||(t[23]=(0,o.eW)(" 最新评论优先"))])]),r.filteredComments?((0,o.uX)(),(0,o.CE)("div",ks,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.comments,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.comment_id,class:"comment"},[(0,o.Lk)("div",vs,[(0,o.Lk)("strong",null,(0,l.v_)(e.nickname),1),(0,o.Lk)("span",Cs,"发表于 "+(0,l.v_)(r.formatTime(e.comment_time)),1),(0,o.Lk)("span",{class:(0,l.C4)(["like-section",{liked:e.is_liked}]),onClick:t=>r.toggleLike(e)}," ❤ "+(0,l.v_)(e.like_count),11,bs)]),(0,o.Lk)("div",ys,(0,l.v_)(e.comment_content),1),(0,o.Lk)("div",fs,[(0,o.Lk)("span",null,[t[24]||(t[24]=(0,o.eW)("评分: ")),(0,o.Lk)("strong",Ls,(0,l.v_)(e.rating),1)]),e.deleteable?((0,o.uX)(),(0,o.CE)("button",{key:0,onClick:t=>r.deleteComment(e.comment_id),class:"delete-btn"}," 删除 ",8,ws)):((0,o.uX)(),(0,o.CE)("button",{key:1,class:"chat-start-btn",onClick:t=>r.openChatModal(e.comment_id)}," 发起聊天 ",8,_s))])])))),128))])):((0,o.uX)(),(0,o.CE)("p",Ss,"本课程暂无评论。")),i.isChatModalVisible?((0,o.uX)(),(0,o.CE)("div",Es,[(0,o.Lk)("div",xs,[(0,o.Lk)("span",{class:"chat-close-btn",onClick:t[7]||(t[7]=(...e)=>r.closeChatModal&&r.closeChatModal(...e))},"×"),t[25]||(t[25]=(0,o.Lk)("h3",null,"发起聊天",-1)),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.chatMessage=e),placeholder:"请输入聊天内容(至少6个字符)",class:"chat-textarea"},null,512),[[a.Jo,i.chatMessage]]),(0,o.Lk)("div",Ps,[(0,o.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>r.submitChat&&r.submitChat(...e)),disabled:i.chatMessage.length<6},"发起",8,Ms)])])])):(0,o.Q3)("",!0),i.isConversationExistsModalVisible?((0,o.uX)(),(0,o.CE)("div",Ts,[(0,o.Lk)("div",Is,[(0,o.Lk)("span",{class:"chat-close-btn",onClick:t[10]||(t[10]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"×"),t[26]||(t[26]=(0,o.Lk)("h3",null,"在此课程下,您与此用户已有会话!",-1)),(0,o.Lk)("div",Xs,[(0,o.Lk)("button",{onClick:t[11]||(t[11]=e=>r.navigateToConversation(i.existingConversationId))},"进入会话"),(0,o.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"取消")])])])):(0,o.Q3)("",!0),(0,o.Lk)("div",js,[(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[13]||(t[13]=e=>i.nickname=e),placeholder:"一句话概括您的评论,如:被x老师伤透了心"},null,512),[[a.Jo,i.nickname]]),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[14]||(t[14]=e=>i.commentContent=e),placeholder:"我们推荐您分享本课程的课程内容、学习难度、考核方式和给分好坏,以帮助更多同学做出判断。支持删除自己的评论。",style:{resize:"none",height:"50px"}},null,512),[[a.Jo,i.commentContent]]),(0,o.Lk)("button",{onClick:t[15]||(t[15]=(...e)=>r.submitComment&&r.submitComment(...e))},"提交评论")])])])])):(0,o.Q3)("",!0)}var Fs={props:{isVisible:{type:Boolean,required:!0},courseId:{type:[Number,String],required:!0}},data(){return{loading:!1,course:{},token:null,userRating:0,totalRating:0,fiveStarPercent:0,fourStarPercent:0,threeStarPercent:0,twoStarPercent:0,oneStarPercent:0,comments:[],nickname:"",commentContent:"",sortBy:"like_count",showShareModal:!1,cachedEmail:null,isChatModalVisible:!1,isConversationExistsModalVisible:!1,chatMessage:"",currentCommentId:null,existingConversationId:null,showErrorModal:!1,aiSummary:null,displayedSummary:"",isTyping:!1,shouldStopTyping:!1}},watch:{courseId:{immediate:!0,handler(e){e&&this.isVisible&&this.loadCourseData()}},isVisible(e){e&&this.courseId&&this.loadCourseData()},displayedSummary(){this.isTyping&&this.$nextTick((()=>{const e=document.querySelector(".course-detail");e&&(e.scrollTop=e.scrollHeight)}))}},computed:{filteredComments(){return this.comments.length>0?this.comments:null}},methods:{async loadCourseData(){if(this.courseId){this.loading=!0,this.course={},this.aiSummary=null,this.displayedSummary="",this.isTyping=!1,this.shouldStopTyping=!1;try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/course-detail?course_id=${this.courseId}`);if(!e.ok)throw new Error("Failed to fetch course detail");this.course=await e.json(),this.getToken(),await Promise.all([this.fetchAndCacheEmail(),this.fetchRatingDistribution(),this.fetchUserRating(),this.fetchComments(),this.fetchAISummary()])}catch(e){console.error("Error loading course data:",e)}finally{this.loading=!1}}},getToken(){const e=document.cookie.split("; ").find((e=>e.startsWith("token=")));e?this.token=e.split("=")[1]:(console.error("Token not found in cookies"),this.token=null)},closeModal(){this.shouldStopTyping=!0,this.isTyping=!1,this.displayedSummary="",this.aiSummary=null,this.$emit("close")},getCategoryName(e){const t={1:"选修课-通识选修类",2:"选修课-人文选修类",3:"选修课-专业方向类",4:"选修课-体育类",5:"选修课-学科基础类",6:"选修课-暑期国际课",7:"选修课-数学与自然科学类",8:"选修课-重修专栏",9:"必修课-数学与自然科学类",10:"必修课-人文社会科学类",11:"必修课-学科基础类",12:"必修课-专业方向类",13:"必修课-实践类"};return t[e]||"未知分类"},async fetchRatingDistribution(){const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-course-ratings-distribution?course_id=${this.course.course_id}`);if(e.ok){const t=await e.json();this.totalRating=t.total_rating||0,this.fiveStarPercent=100*t.five_stars,this.fourStarPercent=100*t.four_stars,this.threeStarPercent=100*t.three_stars,this.twoStarPercent=100*t.two_stars,this.oneStarPercent=100*t.one_star}else 404===e.status&&(this.totalRating=0,this.fiveStarPercent=0,this.fourStarPercent=0,this.threeStarPercent=0,this.twoStarPercent=0,this.oneStarPercent=0)},async fetchUserRating(){const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-user-rating?course_id=${this.course.course_id}`,{headers:{Authorization:this.token}});if(200===e.status){const t=await e.json();this.userRating=t.rating}else this.userRating=0},highlightStars(e){this.userRating=e},resetStars(){this.fetchUserRating()},confirmRating(e){confirm(`您确定要给课程 "${this.course.course_name}" 评分:${e}.0 吗?如您之前有评分记录,此评分将覆盖之前的评分。`)&&this.submitRating(e)},async submitRating(e){const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-rating",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.course.course_id,rating:e})});t.ok&&(this.fetchRatingDistribution(),this.fetchUserRating())},async typewriterEffect(e,t=10){this.isTyping=!0,this.displayedSummary="",this.shouldStopTyping=!1;for(let s=0;ssetTimeout(e,t)))}this.isTyping=!1},async fetchAISummary(){try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/ai_summary/summary?course_id=${this.course.course_id}`);if(!e.ok){if(404===e.status)return this.aiSummary=null,void(this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。");throw new Error("获取AI总结失败")}const t=await e.json();t.summary?(this.aiSummary=t.summary,await this.typewriterEffect(this.aiSummary)):this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。"}catch(e){console.error("生成AI总结失败:",e),this.displayedSummary="生成AI总结时出错,请稍后再试。"}},async fetchComments(){try{if(!this.token)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-comments?course_id=${this.course.course_id}&sort_by=${this.sortBy}`,{headers:{Authorization:this.token}});if(403===e.status)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);if(404===e.status)return void(this.comments=[]);if(!e.ok)throw new Error("获取评论失败");const t=await e.json();this.comments=t.comments}catch(e){console.error("获取评论失败:",e),this.showErrorModal=!0,setTimeout((()=>{window.location.reload()}),2e3)}},async toggleLike(e){e.is_liked?await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/unlike-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e.comment_id})}):await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/like-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e.comment_id})}),this.fetchComments()},async submitComment(){this.nickname.length<3||this.commentContent.length<6?alert("您的昵称请至少包含3个字符,评论请至少包含6个字符。"):(await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.course.course_id,nickname:this.nickname,comment_content:this.commentContent})}),this.fetchComments(),this.nickname="",this.commentContent="")},formatTime(e){const t=new Date(e),s=t.getFullYear(),a=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${a}-${o} ${n}:${i}`},async fetchAndCacheEmail(){if(!this.cachedEmail)if(this.token)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token}}),t=await e.json();e.ok&&t.email?this.cachedEmail=t.email:console.error("JWT验证失败或未找到邮箱")}catch(e){console.error("JWT验证时出错:",e)}else console.error("未找到JWT信息")},getUserEmailFromCookie(){return this.cachedEmail?this.cachedEmail:(console.error("邮箱尚未缓存"),"")},base64Encode(e){return btoa(e)},shareCourse(){const e=this.course.course_name,t=this.base64Encode(this.course.course_id.toString());let s="";s=0!==this.totalRating?`我在NEU小站为课程【${e}】评分,当前评分【${this.totalRating}】,点击【https://course.xn--xhq44jb2fzpc.com/courses?c=${t}】加入评分吧!`:`我在NEU小站为课程【${e}】评分,点击【https://course.xn--xhq44jb2fzpc.com/courses?c=${t}】加入评分吧!`,this.copyToClipboard(s),this.showShareModal=!0,setTimeout((()=>{this.showShareModal=!1}),3e3)},copyToClipboard(e){const t=document.createElement("textarea");t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"},openChatModal(e){this.currentCommentId=e,this.chatMessage="",this.isChatModalVisible=!0},closeChatModal(){this.isChatModalVisible=!1},closeConversationExistsModal(){this.isConversationExistsModalVisible=!1},async submitChat(){if(this.chatMessage.length<6)alert("聊天内容需至少6个字符");else try{const e=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/chat/start-conversation",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:this.currentCommentId,content:this.chatMessage})}),t=await e.json();e.ok&&"Conversation started successfully"===t.message?this.$router.push(`/chat?mid=${t.conversation_id}`):e.ok&&"Conversation already exists"===t.message?(this.existingConversationId=t.conversation_id,this.isConversationExistsModalVisible=!0):"Recipient account status is abnormal, cannot create a conversation"===t.error?alert("此账号状态异常,暂时无法发起聊天!"):"Cannot start a conversation with yourself!"===t.error?alert("不能向自己发起聊天!"):alert("发起会话失败,请稍后再试")}catch(e){console.error("Error starting conversation:",e),alert("发起会话失败,请稍后再试")}finally{this.closeChatModal()}},navigateToConversation(e){this.$router.push(`/chat?mid=${e}`),this.closeConversationExistsModal()},async deleteComment(e){const t=confirm("确定删除评论吗?");if(t)try{const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/delete-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e})});if(t.ok)this.fetchComments();else{const e=await t.json();alert(e.error||"删除评论失败")}}catch(s){console.error("删除评论出错:",s),alert("删除评论失败")}}}};const Ns=(0,C.A)(Fs,[["render",$s],["__scopeId","data-v-9c153036"]]);var As=Ns,zs={components:{CourseDetailModal:As},data(){return{userId:"",activeConversation:null,conversations:[],messages:[],newMessage:"",socket:null,rating:null,selectedCourse:null,selectedCourseId:0,showDetail:!1,isConnected:!1}},async activated(){await this.fetchConversations(),this.activeConversation&&await this.selectConversation(this.activeConversation)},async mounted(){try{const e=this.getCookie("token");if(!e)throw new Error("JWT not found in cookies");const t=JSON.parse(atob(e.split(".")[1]));this.userId=t.id,await this.fetchConversations(),this.checkAndSwitchConversation(),this.initializeWebSocket()}catch(e){console.error("Failed to initialize chat page:",e.message)}},beforeUnmount(){this.socket&&this.socket.close()},methods:{async fetchConversations(){try{const e=await es.A.get("/chat/conversations",{headers:{Authorization:this.getCookie("token")}});this.conversations=[...e.data.conversations]}catch(e){console.error("Failed to fetch conversations:",e)}},formatDate(e){const t=new Date(e);return t.toLocaleString()},async loadCourseDetail(e){try{const t=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/course-detail?course_id=${e}`),s=await t.json();this.selectedCourse=s,this.showDetail=!0}catch(t){console.error("Error loading course details:",t)}},closeCourseDetail(){this.showDetail=!1,this.selectedCourse=null},initializeWebSocket(){const e=this.getCookie("token");if(!e)return void console.error("WebSocket initialization failed: No token found");const t=`${"https:"===window.location.protocol?"wss://coursesystem.xn--xhq44jb2fzpc.com":"ws://49.232.202.164:8080"}/chat?token=${e}`;console.log(`Attempting to connect to WebSocket at: ${t}`),this.socket=new WebSocket(t),this.socket.onopen=()=>{this.isConnected=!0,console.log("WebSocket connected")},this.socket.onmessage=async e=>{try{const t=JSON.parse(e.data);switch(console.log("Received WebSocket message:",t),t.type){case"new_conversation":await this.fetchConversations(),t.conversation_id===this.activeConversation&&await this.selectConversation(t.conversation_id);break;case"new_message":await this.fetchConversations(),t.conversation_id===this.activeConversation&&await this.selectConversation(t.conversation_id);break;case"message_read":if(t.conversation_id===this.activeConversation){const e=this.messages.findIndex((e=>e.message_id===t.message_id&&1===e.sender));-1!==e&&this.$set(this.messages[e],"is_read",!0)}break;case"conversation_read":t.conversation_id===this.activeConversation&&this.messages.forEach((e=>{1===e.sender&&t.message_ids.includes(e.message_id)&&(e.is_read=!0)}));break;default:console.warn(`Unknown WebSocket message type: ${t.type}`)}}catch(t){console.error("Error processing WebSocket message:",t)}},this.socket.onclose=e=>{this.isConnected=!1,console.warn(`WebSocket disconnected: Code ${e.code}, Reason: ${e.reason}`),this.reconnectWebSocket()},this.socket.onerror=e=>{console.error("WebSocket error:",e)}},reconnectWebSocket(){console.warn("Attempting to reconnect WebSocket..."),setTimeout((async()=>{try{this.initializeWebSocket();const e=new Promise(((e,t)=>{const s=setInterval((()=>{this.socket&&this.socket.readyState===WebSocket.OPEN&&(clearInterval(s),e())}),500);setTimeout((()=>{clearInterval(s),t(new Error("WebSocket reconnect timeout"))}),1e4)}));await e,this.isConnected=!0,console.log("WebSocket reconnected successfully"),await this.fetchConversations(),this.activeConversation&&await this.selectConversation(this.activeConversation)}catch(e){console.error("Failed to reconnect WebSocket:",e)}}),5e3)},async selectConversation(e){this.activeConversation=e;try{const t=this.conversations.find((t=>t.conversation_id===e));if(!t)throw new Error("Conversation not found");this.selectedCourseId=t.course_id;const s=await es.A.get("/chat/conversation-messages",{params:{conversation_id:e,course_name:t.course_name},headers:{Authorization:this.getCookie("token")}});this.messages=[...s.data.messages],this.rating=s.data.rating||null,this.$nextTick((()=>{this.scrollToBottom()})),await this.markMessagesAsRead()}catch(t){console.error("Failed to fetch conversation messages:",t)}},async markMessagesAsRead(){try{await es.A.post("/chat/read-conversation",{conversation_id:this.activeConversation},{headers:{Authorization:this.getCookie("token")}}),this.messages.forEach((e=>{0!==e.sender||e.is_read||(e.is_read=!0)}))}catch(e){console.error("Failed to mark messages as read:",e)}},async sendMessage(){if(!this.newMessage.trim())return;const e=this.newMessage;this.newMessage="";try{const t=await es.A.post("/chat/send-message",{conversation_id:this.activeConversation,content:e},{headers:{Authorization:this.getCookie("token")}});this.messages.push({message_id:t.data.message_id,content:e,sender:1,created_at:(new Date).toISOString(),is_read:!1}),this.$nextTick((()=>{this.scrollToBottom()})),await this.markMessagesAsRead(),await this.fetchConversations()}catch(t){console.error("Failed to send message:",t)}},scrollToBottom(){setTimeout((()=>{const e=this.$refs.messageScrollbar;if(e){const t=e.$el.querySelector(".el-scrollbar__wrap");t&&(t.scrollTop=t.scrollHeight)}}),50)},handleKeyDown(e){e.ctrlKey&&"Enter"===e.key&&this.sendMessage()},getCookie(e){const t=document.cookie.split("; ");for(let s=0;se.conversation_id===t));s?await this.selectConversation(t):console.warn("Conversation not found for ID:",t)}}};const Ws=(0,C.A)(zs,[["render",Zt],["__scopeId","data-v-38851032"]]);var Us=Ws;const Os={class:"about-container"},Vs={class:"about-page"},Rs={class:"version-timeline"};function Ds(e,t){const s=(0,o.g2)("el-timeline-item"),a=(0,o.g2)("el-timeline");return(0,o.uX)(),(0,o.CE)("div",Os,[(0,o.Lk)("div",Vs,[t[6]||(t[6]=(0,o.Lk)("div",{class:"project-intro"},[(0,o.Lk)("h2",null,"关于本项目"),(0,o.Lk)("div",{class:"intro-content"},[(0,o.Lk)("p",null,"NEU小站课程评分系统是专门为东北大学学生设计的课程评价平台。本系统采用全匿名方式,学生可以匿名对课程进行评分和发表评论,帮助其他同学更好地了解课程信息。"),(0,o.Lk)("p",null,"系统支持选修课和必修课的评分,包括通识选修、人文选修、专业方向等多个类别。为了保护用户隐私,发表评论时不会显示用户在NEU小站的用户名,每次评论的昵称均由用户自行定义。"),(0,o.Lk)("p",null,"本系统仅对完成NEU小站校园认证的用户开放,确保信息的真实性和可靠性。未来本系统还计划为校内用户开放评分数据下载。")])],-1)),(0,o.Lk)("div",Rs,[t[5]||(t[5]=(0,o.Lk)("h2",null,"更新日志",-1)),(0,o.bF)(a,null,{default:(0,o.k6)((()=>[(0,o.bF)(s,{timestamp:"2025年12月",placement:"top"},{default:(0,o.k6)((()=>t[0]||(t[0]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v2.0"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"重构响应式UI,优化移动端用户体验。暂时下线聊天功能。")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2025年2月",placement:"top"},{default:(0,o.k6)((()=>t[1]||(t[1]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.4"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"优化页面样式和用户体验")])],-1),(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.3"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"新增AI课程总结功能,接入DeepSeek V3大模型")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2025年1月",placement:"top"},{default:(0,o.k6)((()=>t[2]||(t[2]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.2"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"评论区支持删除自己的评论"),(0,o.Lk)("li",null,'优化了"评分由低到高"排序的逻辑,会先展示有评分(评分不为0)的课程'),(0,o.Lk)("li",null,"新增了2024-2025学年春季学期的140门通识选修课")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2024年11月",placement:"top"},{default:(0,o.k6)((()=>t[3]||(t[3]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.0"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"新增在线聊天功能"),(0,o.Lk)("li",null,"支持从评论发起聊天")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2024年9月",placement:"top"},{default:(0,o.k6)((()=>t[4]||(t[4]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.0.2"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"新增必修课评分功能"),(0,o.Lk)("li",null,"增加课程类别"),(0,o.Lk)("li",null,"更新用户验证相关接口,增强安全性"),(0,o.Lk)("li",null,"修复部分Bug")])],-1),(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.0.0"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"课程评分系统正式上线(测试版)")])],-1)]))),_:1})])),_:1})])])])}const qs={},Bs=(0,C.A)(qs,[["render",Ds],["__scopeId","data-v-5c1b02c2"]]);var Qs=Bs;const Js={class:"course-detail-page"},Ks={key:0,class:"loading-state"},Hs={key:1,class:"container"},Gs={class:"top-section"},Ys={class:"info-card card"},Zs={class:"card-header"},ea={class:"course-name"},ta={key:0,class:"tags"},sa={class:"info-grid"},aa={class:"info-item"},oa={class:"value"},na={class:"info-item"},ia={class:"value"},ra={class:"info-item full-width"},ca={class:"value"},la={class:"action-area"},ua={class:"rating-card card"},da={class:"rating-overview"},ha={class:"total-score"},ma={class:"score"},pa={class:"count"},ga={class:"user-rating-action"},ka={class:"stars interactive"},va=["onMouseover","onClick"],Ca={class:"rating-bars"},ba={class:"bar-row"},ya={class:"percent"},fa={class:"bar-row"},La={class:"percent"},wa={class:"bar-row"},_a={class:"percent"},Sa={class:"bar-row"},Ea={class:"percent"},xa={class:"bar-row"},Pa={class:"percent"},Ma={class:"ai-section card"},Ta={class:"ai-content"},Ia={key:0,class:"summary-text"},Xa={key:0,class:"cursor"},ja={key:1,class:"empty-text"},$a={class:"comments-section card"},Fa={class:"section-header"},Na={class:"sort-tabs"},Aa={class:"post-comment"},za={class:"input-group"},Wa={key:0,class:"comments-list"},Ua={class:"comment-header"},Oa={class:"comment-author"},Va={class:"comment-date"},Ra={class:"comment-body"},Da={class:"comment-footer"},qa={class:"rating-tag"},Ba={class:"actions"},Qa=["onClick"],Ja=["onClick"],Ka={key:1,class:"no-comments"},Ha={key:0,class:"toast"},Ga={key:0,class:"toast error"},Ya={key:2,class:"modal-overlay"},Za={class:"modal-box"},eo={class:"modal-actions"},to=["disabled"],so={key:3,class:"modal-overlay"},ao={class:"modal-box"},oo={class:"modal-actions"};function no(e,t,s,n,i,r){const c=(0,o.g2)("el-progress");return(0,o.uX)(),(0,o.CE)("div",Js,[i.loading?((0,o.uX)(),(0,o.CE)("div",Ks,t[13]||(t[13]=[(0,o.Lk)("div",{class:"spinner"},null,-1),(0,o.Lk)("p",null,"正在加载课程详情...",-1)]))):((0,o.uX)(),(0,o.CE)("div",Hs,[(0,o.Lk)("div",Gs,[(0,o.Lk)("div",Ys,[(0,o.Lk)("div",Zs,[(0,o.Lk)("h1",ea,[(0,o.eW)((0,l.v_)(i.course.course_name)+" ",1),i.course.titles&&i.course.titles.length>0?((0,o.uX)(),(0,o.CE)("div",ta,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.course.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"tag",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128))])):(0,o.Q3)("",!0)])]),(0,o.Lk)("div",sa,[(0,o.Lk)("div",aa,[t[14]||(t[14]=(0,o.Lk)("span",{class:"label"},"分类",-1)),(0,o.Lk)("span",oa,(0,l.v_)(r.getCategoryName(i.course.category_id)),1)]),(0,o.Lk)("div",na,[t[15]||(t[15]=(0,o.Lk)("span",{class:"label"},"开课院系",-1)),(0,o.Lk)("span",ia,(0,l.v_)(r.getCollegeName(i.course.college)),1)]),(0,o.Lk)("div",ra,[t[16]||(t[16]=(0,o.Lk)("span",{class:"label"},"教师(团队)",-1)),(0,o.Lk)("span",ca,(0,l.v_)(i.course.teachers),1)])]),(0,o.Lk)("div",la,[(0,o.Lk)("button",{class:"share-btn",onClick:t[0]||(t[0]=(...e)=>r.shareCourse&&r.shareCourse(...e))},t[17]||(t[17]=[(0,o.Lk)("span",{class:"icon"},"🔗",-1),(0,o.eW)(" 复制链接 ")]))])]),(0,o.Lk)("div",ua,[t[24]||(t[24]=(0,o.Lk)("h3",null,"课程评分",-1)),(0,o.Lk)("div",da,[(0,o.Lk)("div",ha,[(0,o.Lk)("span",ma,(0,l.v_)(i.totalRating),1),(0,o.Lk)("span",pa,"("+(0,l.v_)(i.course.rating_count||0)+"人评分)",1)]),(0,o.Lk)("div",ga,[t[18]||(t[18]=(0,o.Lk)("p",null,"您的评分",-1)),(0,o.Lk)("div",ka,[((0,o.uX)(),(0,o.CE)(o.FK,null,(0,o.pI)(5,(e=>(0,o.Lk)("span",{key:e,class:(0,l.C4)({active:e<=i.userRating}),onMouseover:t=>r.highlightStars(e),onMouseout:t[1]||(t[1]=(...e)=>r.resetStars&&r.resetStars(...e)),onClick:t=>r.confirmRating(e)},"★",42,va))),64))])])]),(0,o.Lk)("div",Ca,[(0,o.Lk)("div",ba,[t[19]||(t[19]=(0,o.Lk)("span",{class:"star-label"},"5星",-1)),(0,o.bF)(c,{percentage:i.fiveStarPercent,status:"success","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",ya,(0,l.v_)(i.fiveStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",fa,[t[20]||(t[20]=(0,o.Lk)("span",{class:"star-label"},"4星",-1)),(0,o.bF)(c,{percentage:i.fourStarPercent,status:"success","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",La,(0,l.v_)(i.fourStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",wa,[t[21]||(t[21]=(0,o.Lk)("span",{class:"star-label"},"3星",-1)),(0,o.bF)(c,{percentage:i.threeStarPercent,status:"warning","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",_a,(0,l.v_)(i.threeStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",Sa,[t[22]||(t[22]=(0,o.Lk)("span",{class:"star-label"},"2星",-1)),(0,o.bF)(c,{percentage:i.twoStarPercent,status:"warning","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",Ea,(0,l.v_)(i.twoStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",xa,[t[23]||(t[23]=(0,o.Lk)("span",{class:"star-label"},"1星",-1)),(0,o.bF)(c,{percentage:i.oneStarPercent,status:"exception","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",Pa,(0,l.v_)(i.oneStarPercent.toFixed(0))+"%",1)])])])]),(0,o.Lk)("div",Ma,[t[25]||(t[25]=(0,o.Lk)("div",{class:"section-header"},[(0,o.Lk)("h2",null,[(0,o.Lk)("span",{class:"icon"},"🤖"),(0,o.eW)(" AI 课程总结 "),(0,o.Lk)("span",{class:"beta-badge"},"Beta")]),(0,o.Lk)("span",{class:"ai-disclaimer"},"内容由 DeepSeek V3 生成,仅供参考")],-1)),(0,o.Lk)("div",Ta,[i.displayedSummary?((0,o.uX)(),(0,o.CE)("div",Ia,[(0,o.eW)((0,l.v_)(i.displayedSummary),1),i.isTyping?((0,o.uX)(),(0,o.CE)("span",Xa,"|")):(0,o.Q3)("",!0)])):((0,o.uX)(),(0,o.CE)("p",ja,"当前课程的评分和评论数据过少,暂不能生成AI总结。"))])]),(0,o.Lk)("div",$a,[(0,o.Lk)("div",Fa,[t[27]||(t[27]=(0,o.Lk)("h2",null,"课程评论",-1)),(0,o.Lk)("div",Na,[(0,o.Lk)("span",{class:(0,l.C4)({active:"like_count"===i.sortBy}),onClick:t[2]||(t[2]=e=>r.changeSort("like_count"))},"最热",2),t[26]||(t[26]=(0,o.Lk)("span",{class:"divider"},"|",-1)),(0,o.Lk)("span",{class:(0,l.C4)({active:"comment_time"===i.sortBy}),onClick:t[3]||(t[3]=e=>r.changeSort("comment_time"))},"最新",2)])]),(0,o.Lk)("div",Aa,[(0,o.Lk)("div",za,[(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.nickname=e),placeholder:"一句话概括您的评论",class:"nickname-input"},null,512),[[a.Jo,i.nickname]]),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[5]||(t[5]=e=>i.commentContent=e),placeholder:"分享您的课程体验、学习难度、考核方式等...",class:"comment-textarea"},null,512),[[a.Jo,i.commentContent]])]),(0,o.Lk)("button",{onClick:t[6]||(t[6]=(...e)=>r.submitComment&&r.submitComment(...e)),class:"submit-btn"},"提交评论")]),r.filteredComments&&r.filteredComments.length>0?((0,o.uX)(),(0,o.CE)("div",Wa,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.comments,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.comment_id,class:"comment-item"},[(0,o.Lk)("div",Ua,[(0,o.Lk)("span",Oa,(0,l.v_)(e.nickname),1),(0,o.Lk)("span",Va,(0,l.v_)(r.formatTime(e.comment_time)),1)]),(0,o.Lk)("div",Ra,(0,l.v_)(e.comment_content),1),(0,o.Lk)("div",Da,[(0,o.Lk)("div",qa,[t[28]||(t[28]=(0,o.eW)(" 评分: ")),(0,o.Lk)("span",null,(0,l.v_)(e.rating),1)]),(0,o.Lk)("div",Ba,[(0,o.Lk)("span",{class:(0,l.C4)(["like-btn",{liked:e.is_liked}]),onClick:t=>r.toggleLike(e)}," ❤ "+(0,l.v_)(e.like_count),11,Qa),e.deleteable?((0,o.uX)(),(0,o.CE)("button",{key:0,onClick:t=>r.deleteComment(e.comment_id),class:"action-link delete"}," 删除 ",8,Ja)):(0,o.Q3)("",!0)])])])))),128))])):((0,o.uX)(),(0,o.CE)("div",Ka,t[29]||(t[29]=[(0,o.Lk)("p",null,"暂无评论,快来抢沙发吧!",-1)])))])])),(0,o.bF)(a.eB,{name:"fade"},{default:(0,o.k6)((()=>[i.showShareModal?((0,o.uX)(),(0,o.CE)("div",Ha," 链接复制成功,快去分享给其他小伙伴吧! ")):(0,o.Q3)("",!0)])),_:1}),(0,o.bF)(a.eB,{name:"fade"},{default:(0,o.k6)((()=>[i.showErrorModal?((0,o.uX)(),(0,o.CE)("div",Ga," 获取数据失败,正在刷新页面... ")):(0,o.Q3)("",!0)])),_:1}),i.isChatModalVisible?((0,o.uX)(),(0,o.CE)("div",Ya,[(0,o.Lk)("div",Za,[(0,o.Lk)("span",{class:"close-btn",onClick:t[7]||(t[7]=(...e)=>r.closeChatModal&&r.closeChatModal(...e))},"×"),t[30]||(t[30]=(0,o.Lk)("h3",null,"发起聊天",-1)),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.chatMessage=e),placeholder:"请输入聊天内容(至少6个字符)",class:"modal-textarea"},null,512),[[a.Jo,i.chatMessage]]),(0,o.Lk)("div",eo,[(0,o.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>r.submitChat&&r.submitChat(...e)),disabled:i.chatMessage.length<6,class:"primary-btn"},"发起",8,to)])])])):(0,o.Q3)("",!0),i.isConversationExistsModalVisible?((0,o.uX)(),(0,o.CE)("div",so,[(0,o.Lk)("div",ao,[(0,o.Lk)("span",{class:"close-btn",onClick:t[10]||(t[10]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"×"),t[31]||(t[31]=(0,o.Lk)("h3",null,"提示",-1)),t[32]||(t[32]=(0,o.Lk)("p",null,"在此课程下,您与此用户已有会话!",-1)),(0,o.Lk)("div",oo,[(0,o.Lk)("button",{onClick:t[11]||(t[11]=e=>r.navigateToConversation(i.existingConversationId)),class:"primary-btn"},"进入会话"),(0,o.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e)),class:"secondary-btn"},"取消")])])])):(0,o.Q3)("",!0)])}var io={name:"CourseDetail",data(){return{courseId:null,loading:!0,course:{},token:null,userRating:0,totalRating:0,fiveStarPercent:0,fourStarPercent:0,threeStarPercent:0,twoStarPercent:0,oneStarPercent:0,comments:[],nickname:"",commentContent:"",sortBy:"like_count",showShareModal:!1,cachedEmail:null,isChatModalVisible:!1,isConversationExistsModalVisible:!1,chatMessage:"",currentCommentId:null,existingConversationId:null,showErrorModal:!1,aiSummary:null,displayedSummary:"",isTyping:!1,shouldStopTyping:!1}},computed:{filteredComments(){return this.comments.length>0?this.comments:null}},async created(){this.courseId=this.$route.params.course_id,this.courseId?(await this.loadCourseData(),this.course&&this.course.course_name&&(document.title=this.course.course_name+" ("+this.course.teachers+") - NEU小站课程评分系统")):(this.loading=!1,this.$router.replace("/404"))},beforeUnmount(){this.shouldStopTyping=!0},methods:{async loadCourseData(){this.loading=!0,this.course={},this.aiSummary=null,this.displayedSummary="",this.isTyping=!1,this.shouldStopTyping=!1;try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/course-detail?course_id=${this.courseId}`);if(404===e.status)return void this.$router.replace("/404");if(!e.ok)throw new Error("Failed to fetch course detail");this.course=await e.json(),this.getToken(),await Promise.all([this.fetchAndCacheEmail(),this.fetchRatingDistribution(),this.fetchUserRating(),this.fetchComments(),this.fetchAISummary()])}catch(e){console.error("Error loading course data:",e)}finally{this.loading=!1}},getToken(){const e=document.cookie.split("; ").find((e=>e.startsWith("token=")));this.token=e?e.split("=")[1]:null},changeSort(e){this.sortBy!==e&&(this.sortBy=e,this.fetchComments())},getCategoryName(e){const t={1:"选修课-通识选修类",2:"选修课-人文选修类",3:"选修课-专业方向类",4:"选修课-体育类",5:"选修课-学科基础类",6:"选修课-暑期国际课",7:"选修课-数学与自然科学类",8:"选修课-重修专栏",9:"必修课-数学与自然科学类",10:"必修课-人文社会科学类",11:"必修课-学科基础类",12:"必修课-专业方向类",13:"必修课-实践类"};return t[e]||"未知分类"},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"},async fetchRatingDistribution(){const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-course-ratings-distribution?course_id=${this.courseId}`);if(e.ok){const t=await e.json();this.totalRating=t.total_rating||0,this.fiveStarPercent=100*t.five_stars,this.fourStarPercent=100*t.four_stars,this.threeStarPercent=100*t.three_stars,this.twoStarPercent=100*t.two_stars,this.oneStarPercent=100*t.one_star}else this.totalRating=0,this.fiveStarPercent=0,this.fourStarPercent=0,this.threeStarPercent=0,this.twoStarPercent=0,this.oneStarPercent=0},async fetchUserRating(){if(!this.token)return;const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-user-rating?course_id=${this.courseId}`,{headers:{Authorization:this.token}});if(200===e.status){const t=await e.json();this.userRating=t.rating}else this.userRating=0},highlightStars(e){this.userRating=e},resetStars(){this.fetchUserRating()},confirmRating(e){confirm(`您确定要给课程 "${this.course.course_name}" 评分:${e}.0 吗?此评分将覆盖之前的评分。`)&&this.submitRating(e)},async submitRating(e){const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-rating",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.courseId,rating:e})});t.ok&&(this.fetchRatingDistribution(),this.fetchUserRating())},async typewriterEffect(e,t=10){this.isTyping=!0,this.displayedSummary="",this.shouldStopTyping=!1;for(let s=0;ssetTimeout(e,t)))}this.isTyping=!1},async fetchAISummary(){try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/ai_summary/summary?course_id=${this.courseId}`);if(!e.ok)return void(this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。");const t=await e.json();t.summary?(this.aiSummary=t.summary,await this.typewriterEffect(this.aiSummary)):this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。"}catch(e){this.displayedSummary="生成AI总结时出错,请稍后再试。"}},async fetchComments(){try{this.token;const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-comments?course_id=${this.courseId}&sort_by=${this.sortBy}`,{headers:{Authorization:this.token}});if(404===e.status)return void(this.comments=[]);if(!e.ok)throw new Error("获取评论失败");const t=await e.json();this.comments=t.comments}catch(e){console.error(e)}},async toggleLike(e){const t=e.is_liked?"unlike-comment":"like-comment";await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/${t}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e.comment_id})}),this.fetchComments()},async submitComment(){this.nickname.length<2||this.commentContent.length<6?alert("一句话概括请至少包含2个字符,评论请至少包含6个字符。"):(await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.courseId,nickname:this.nickname,comment_content:this.commentContent})}),this.fetchComments(),this.nickname="",this.commentContent="")},async deleteComment(e){if(!confirm("确定删除评论吗?"))return;const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/delete-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e})});t.ok&&this.fetchComments()},formatTime(e){const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},async fetchAndCacheEmail(){if(!this.cachedEmail&&this.token)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token}}),t=await e.json();e.ok&&t.email&&(this.cachedEmail=t.email)}catch(e){console.error(e)}},base64Encode(e){return btoa(e)},shareCourse(){const e=`https://course.xn--xhq44jb2fzpc.com/detail/${this.courseId}`;this.copyToClipboard(e),this.showShareModal=!0,setTimeout((()=>{this.showShareModal=!1}),3e3)},copyToClipboard(e){const t=document.createElement("textarea");t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)},openChatModal(e){this.currentCommentId=e,this.chatMessage="",this.isChatModalVisible=!0},closeChatModal(){this.isChatModalVisible=!1},closeConversationExistsModal(){this.isConversationExistsModalVisible=!1},async submitChat(){if(this.chatMessage.length<6)alert("聊天内容需至少6个字符");else try{const e=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/chat/start-conversation",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:this.currentCommentId,content:this.chatMessage})}),t=await e.json();e.ok&&"Conversation started successfully"===t.message?this.$router.push(`/chat?mid=${t.conversation_id}`):e.ok&&"Conversation already exists"===t.message?(this.existingConversationId=t.conversation_id,this.isConversationExistsModalVisible=!0):alert(t.error||"发起会话失败")}catch(e){alert("发起会话失败,请稍后再试")}finally{this.closeChatModal()}},navigateToConversation(e){this.$router.push(`/chat?mid=${e}`),this.closeConversationExistsModal()}}};const ro=(0,C.A)(io,[["render",no],["__scopeId","data-v-482ee958"]]);var co=ro;const lo={class:"not-found-page"},uo={class:"content"};function ho(e,t,s,a,n,i){const r=(0,o.g2)("router-link");return(0,o.uX)(),(0,o.CE)("div",lo,[(0,o.Lk)("div",uo,[t[1]||(t[1]=(0,o.Lk)("div",{class:"error-icon"},"⚠️",-1)),t[2]||(t[2]=(0,o.Lk)("h1",{class:"error-code"},"404",-1)),t[3]||(t[3]=(0,o.Lk)("p",{class:"error-message"},"未知页面",-1)),t[4]||(t[4]=(0,o.Lk)("p",{class:"description"},"抱歉,您访问的页面不存在或已被移除。",-1)),(0,o.bF)(r,{to:"/",class:"home-btn"},{default:(0,o.k6)((()=>t[0]||(t[0]=[(0,o.eW)("返回首页")]))),_:1})])])}var mo={name:"NotFound",created(){document.title="未知页面 - NEU小站课程评分系统"}};const po=(0,C.A)(mo,[["render",ho],["__scopeId","data-v-655c3ea4"]]);var go=po;const ko=[{path:"/",name:"home",meta:{title:"NEU小站课程评分系统"},component:X},{path:"/courses",name:"course-list",meta:{title:"我的课程 - NEU小站课程评分系统"},component:Ce},{path:"/rating",name:"rating",meta:{title:"选修课列表 - NEU小站课程评分系统"},component:tt},{path:"/ratingforcomp",name:"ratingforcomp",meta:{title:"必修课列表 - NEU小站课程评分系统"},component:zt},{path:"/chat",name:"chat",meta:{title:"我的聊天 - NEU小站课程评分系统"},component:Us},{path:"/about",name:"about",meta:{title:"关于 - NEU小站课程评分系统"},component:Qs},{path:"/detail/:course_id",name:"course-detail",meta:{title:"课程详情 - NEU小站课程评分系统"},component:co},{path:"/404",name:"NotFound",meta:{title:"404 - 未知页面 - NEU小站课程评分系统"},component:go},{path:"/:pathMatch(.*)*",redirect:"/404"}],vo=(0,S.aE)({history:(0,S.LA)(),routes:ko});vo.beforeEach(((e,t,s)=>{document.title=e.meta.title||"默认标题",s()}));var Co=vo;const bo=(0,a.Ef)(w);bo.use(Co),bo.use(_.A),bo.mount("#app"),es.A.defaults.baseURL="https://coursesystem.xn--xhq44jb2fzpc.com/",bo.config.globalProperties.$axios=es.A}},t={};function s(a){var o=t[a];if(void 0!==o)return o.exports;var n=t[a]={exports:{}};return e[a].call(n.exports,n,n.exports,s),n.exports}s.m=e,function(){var e=[];s.O=function(t,a,o,n){if(!a){var i=1/0;for(u=0;u=n)&&Object.keys(s.O).every((function(e){return s.O[e](a[c])}))?a.splice(c--,1):(r=!1,n0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[a,o,n]}}(),function(){s.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return s.d(t,{a:t}),t}}(),function(){s.d=function(e,t){for(var a in t)s.o(t,a)&&!s.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})}}(),function(){s.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){s.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}}(),function(){var e={524:0};s.O.j=function(t){return 0===e[t]};var t=function(t,a){var o,n,i=a[0],r=a[1],c=a[2],l=0;if(i.some((function(t){return 0!==e[t]}))){for(o in r)s.o(r,o)&&(s.m[o]=r[o]);if(c)var u=c(s)}for(t&&t(a);l您的访问被拒绝

只有在 NEU小站 完成 校园网或校园邮箱验证 的用户才能访问课程评分系统。

请确保您已完成相关操作,然后重新尝试访问。

',4)])))])}s(4114);var l=s(4232);const u={class:"navbar"},d={class:"navbar-container"},h={class:"navbar-menu desktop-only"},m={class:"hamburger-box"},p={key:0,class:"mobile-menu-content"},g={class:"mobile-links"};function k(e,t,s,n,i,r){const c=(0,o.g2)("router-link");return(0,o.uX)(),(0,o.CE)("nav",u,[(0,o.Lk)("div",d,[(0,o.Lk)("div",{class:"navbar-brand",onClick:t[0]||(t[0]=t=>e.$router.push("/"))},t[3]||(t[3]=[(0,o.Lk)("img",{src:"https://download.xn--xhq44jb2fzpc.com/images/logo-hd.png",alt:"NEU小站",class:"logo"},null,-1),(0,o.Lk)("span",{class:"brand-text"},"课程评分",-1),(0,o.Lk)("span",{class:"version-badge"},"V2",-1)])),(0,o.Lk)("div",h,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.menuItems,(e=>((0,o.uX)(),(0,o.Wv)(c,{key:e.name,to:e.path,class:"nav-item","active-class":"active"},{default:(0,o.k6)((()=>[(0,o.eW)((0,l.v_)(e.label),1)])),_:2},1032,["to"])))),128))]),(0,o.Lk)("button",{class:"navbar-toggle mobile-only",onClick:t[1]||(t[1]=(...e)=>r.toggleMenu&&r.toggleMenu(...e)),"aria-label":"Toggle navigation"},[(0,o.Lk)("span",m,[(0,o.Lk)("span",{class:(0,l.C4)(["hamburger-inner",{"is-active":i.isMenuOpen}])},null,2)])])]),(0,o.bF)(a.eB,{name:"fade"},{default:(0,o.k6)((()=>[i.isMenuOpen?((0,o.uX)(),(0,o.CE)("div",{key:0,class:"mobile-menu-overlay",onClick:t[2]||(t[2]=(...e)=>r.closeMenu&&r.closeMenu(...e))})):(0,o.Q3)("",!0)])),_:1}),(0,o.bF)(a.eB,{name:"slide-down"},{default:(0,o.k6)((()=>[i.isMenuOpen?((0,o.uX)(),(0,o.CE)("div",p,[t[4]||(t[4]=(0,o.Lk)("div",{class:"mobile-menu-header"},[(0,o.Lk)("span",{class:"mobile-menu-title"},"菜单")],-1)),(0,o.Lk)("div",g,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.menuItems,(e=>((0,o.uX)(),(0,o.Wv)(c,{key:e.name,to:e.path,class:"mobile-nav-item","active-class":"active",onClick:r.closeMenu},{default:(0,o.k6)((()=>[(0,o.eW)((0,l.v_)(e.label),1)])),_:2},1032,["to","onClick"])))),128))]),t[5]||(t[5]=(0,o.Lk)("div",{class:"mobile-footer"},[(0,o.eW)(" © 2025 "),(0,o.Lk)("a",{href:"https://www.xn--xhq44jb2fzpc.com",target:"_blank",style:{color:"inherit","text-decoration":"none"}},"NEU小站")],-1))])):(0,o.Q3)("",!0)])),_:1})])}var v={name:"NavBar",data(){return{isMenuOpen:!1,menuItems:[{label:"使用必看",path:"/",name:"home"},{label:"选修课评分",path:"/rating",name:"rating"},{label:"必修课评分",path:"/ratingforcomp",name:"ratingforcomp"},{label:"我的课程",path:"/courses",name:"course-list"},{label:"关于",path:"/about",name:"about"}]}},methods:{toggleMenu(){this.isMenuOpen=!this.isMenuOpen},closeMenu(){this.isMenuOpen=!1}}},C=s(1241);const b=(0,C.A)(v,[["render",k],["__scopeId","data-v-2d6400c2"]]);var y=b,f={name:"App",data(){return{isAuthorized:!1,authChecked:!1}},components:{NavBar:y},mounted(){this.checkLoginStatus()},methods:{async checkLoginStatus(){const e=document.cookie.split("; ").reduce(((e,t)=>{const[s,a]=t.split("=");return s&&a&&(e[s.trim()]=decodeURIComponent(a)),e}),{}).token;if(e)try{const t=await fetch("https://newfront.xn--xhq44jb2fzpc.com/user/info",{method:"GET",headers:{Authorization:e}}),s=await t.json();t.ok&&!0===s.activated?this.isAuthorized=!0:console.warn("用户未通过验证:用户未激活")}catch(t){console.error("获取用户信息失败:",t)}finally{this.authChecked=!0}}}};const L=(0,C.A)(f,[["render",c]]);var w=L,_=s(6762),S=(s(4188),s(973));const E={key:0},x={id:"homepage-title"},P={key:1};function M(e,t,s,a,n,i){const r=(0,o.g2)("router-link");return n.isLoaded?((0,o.uX)(),(0,o.CE)("div",E,[(0,o.Lk)("div",null,[(0,o.Lk)("h2",x,(0,l.v_)(n.greeting)+", "+(0,l.v_)(n.nickname)+"!",1),t[9]||(t[9]=(0,o.Fv)("

欢迎您使用NEU小站课程评分系统!

本系统采用全匿名方式,学生可以匿名对课程进行评分和发表评论。每人对每个课程只能评分一次,若需要多次评分,系统将记录用户最后一次提交的评分结果。为保护隐私,发表评论时不会显示用户在NEU小站的用户名,每次评论的昵称均由用户自行定义。

本系统中,课程分为两大类:选修课和必修课。选修课有8个小类:通识选修、人文选修、专业方向、体育、学科基础、暑期国际课、数学与自然科学、重修专栏。人文选修类包括采用“抢选”方式进行选课的所有选修课,以及“改革开放史”和“社会主义发展史”两门人文社会科学类的选修课。体育课单独作为一类,不属于人文选修类。重修课程的选课归为选修课的“重修专栏”类别,不属于必修课范畴。重修专栏可以分享任何类别课程,但仅限分享重修体验

必修课有5个小类:数学与自然科学、人文社会科学、学科基础、专业方向、实践。如上所述,本系统中重修的必修课程也属于选修课范畴。特别说明:军训课程属于实践类,系辅导员给分,在创建课程时课程教师请填写辅导员。

",4)),(0,o.Lk)("p",null,[t[1]||(t[1]=(0,o.eW)(" 在创建课程时,请先了解课程的类别,以及课程的")),t[2]||(t[2]=(0,o.Lk)("strong",null,"开课院系",-1)),t[3]||(t[3]=(0,o.eW)(",")),(0,o.bF)(r,{to:"/courses?m=true",class:"guide-link"},{default:(0,o.k6)((()=>t[0]||(t[0]=[(0,o.eW)("点击此处")]))),_:1}),t[4]||(t[4]=(0,o.eW)("查看指引。")),t[5]||(t[5]=(0,o.Lk)("strong",null,'如果同一课程的任课教师不同,用户可以创建多个同名课程,例如"A老师-篮球"和"B老师-篮球"将被视为两个不同的课程。',-1)),t[6]||(t[6]=(0,o.eW)("创建的课程卡片")),t[7]||(t[7]=(0,o.Lk)("strong",null,"需经过管理员审核",-1)),t[8]||(t[8]=(0,o.eW)(',审核进度可在"我的课程"中实时查看。 '))]),t[10]||(t[10]=(0,o.Lk)("p",null,[(0,o.eW)(" 本系统鼓励同学们提供真实、有价值的评分。"),(0,o.Lk)("strong",null,"禁止发布带有侮辱性的人身攻击等恶意评论。"),(0,o.eW)("管理员将对恶意用户进行封禁处理,确保评分系统的文明环境。 ")],-1))])])):((0,o.uX)(),(0,o.CE)("div",P,t[11]||(t[11]=[(0,o.Lk)("p",null,"加载中,请稍后...",-1)])))}var T={data(){return{name:"Homepage",greeting:"",nickname:"",isLoaded:!1}},mounted(){this.setGreeting(),this.fetchNickname(),setTimeout((()=>{this.isLoaded=!0}),300)},methods:{setGreeting(){const e=(new Date).getHours();this.greeting=e<12?"早上好":e<14?"中午好":e<18?"下午好":"晚上好"},async fetchNickname(){const e=document.cookie.split("; ").reduce(((e,t)=>{const[s,a]=t.split("=");return e[s]=decodeURIComponent(a),e}),{}).token;if(e)try{const t=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/avatar/nickname",{method:"GET",headers:{Authorization:e}});if(!t.ok){const e=await t.json();return void console.error("获取昵称失败:",e.message||"未知错误")}const s=await t.json();s.nickname?(this.nickname=s.nickname,console.log("Nickname successfully fetched:",s.nickname)):(this.nickname="默认昵称",console.log("Nickname field is missing. Using default nickname."))}catch(t){console.error("获取昵称时出错:",t)}else console.error("未找到JWT信息")}}};const I=(0,C.A)(T,[["render",M],["__scopeId","data-v-b5d4cca8"]]);var X=I;const j={class:"course-list-page"},$={key:0,class:"loading-message"},F={key:1,class:"empty-message"},N={key:2,class:"course-cards"},A=["onClick"],z={class:"card-header"},W={class:"course-name-title"},U={class:"card-body"},O={class:"info-row"},V={class:"info-val"},R={class:"info-row"},D={class:"info-val truncate"},q={class:"info-row"},B={class:"info-val truncate"},Q={class:"card-footer"},J={class:"time-info"},K={class:"time-row"},H={class:"time-val"},G={class:"time-row"},Y={class:"time-val"},Z={key:3,class:"pagination-bar"},ee=["disabled"],te=["onClick"],se=["disabled"],ae={class:"add-course-section card-style"},oe={class:"section-header"},ne={class:"input-grid"},ie={class:"input-group"},re={class:"input-group"},ce={class:"input-group"},le=["value"],ue={class:"input-group"},de={class:"button-group"},he={key:4,class:"help-modal"},me={class:"help-modal-content"},pe={class:"help-modal-header"};function ge(e,t,s,n,i,r){return(0,o.uX)(),(0,o.CE)("div",j,[t[24]||(t[24]=(0,o.Lk)("h2",{class:"page-title"},"我添加的课程",-1)),i.isLoaded?0===i.submissions.length?((0,o.uX)(),(0,o.CE)("div",F," 您还没有添加任何课程。 ")):((0,o.uX)(),(0,o.CE)("div",N,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.paginatedSubmissions,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.submit_id,class:"course-card",onClick:t=>r.handleCardClick(e)},[(0,o.Lk)("div",z,[(0,o.Lk)("h3",W,(0,l.v_)(e.course_name),1),(0,o.Lk)("div",{class:(0,l.C4)(["status-tag",r.getStatusClass(e.status)])},(0,l.v_)(e.status),3)]),(0,o.Lk)("div",U,[(0,o.Lk)("div",O,[t[9]||(t[9]=(0,o.Lk)("span",{class:"info-label"},"分类",-1)),(0,o.Lk)("span",V,(0,l.v_)(r.getCategoryName(e.category_id)),1)]),(0,o.Lk)("div",R,[t[10]||(t[10]=(0,o.Lk)("span",{class:"info-label"},"教师",-1)),(0,o.Lk)("span",D,(0,l.v_)(e.teachers),1)]),(0,o.Lk)("div",q,[t[11]||(t[11]=(0,o.Lk)("span",{class:"info-label"},"院系",-1)),(0,o.Lk)("span",B,(0,l.v_)(r.getCollegeName(e.college)),1)])]),(0,o.Lk)("div",Q,[(0,o.Lk)("div",J,[(0,o.Lk)("div",K,[t[12]||(t[12]=(0,o.Lk)("span",{class:"time-label"},"提交:",-1)),(0,o.Lk)("span",H,(0,l.v_)(r.formatTimeShort(e.create_time)),1)]),(0,o.Lk)("div",G,[t[13]||(t[13]=(0,o.Lk)("span",{class:"time-label"},"更新:",-1)),(0,o.Lk)("span",Y,(0,l.v_)(r.formatTimeShort(e.status_update_time)),1)])])])],8,A)))),128))])):((0,o.uX)(),(0,o.CE)("div",$," 加载中,请稍后... ")),i.totalPages>1?((0,o.uX)(),(0,o.CE)("div",Z,[(0,o.Lk)("button",{onClick:t[0]||(t[0]=e=>r.goToPage(1)),class:(0,l.C4)({active:1===i.currentPage}),disabled:1===i.currentPage},"首页",10,ee),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.getPaginationPages(),(e=>((0,o.uX)(),(0,o.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,l.C4)({active:i.currentPage===e})},(0,l.v_)(e),11,te)))),128)),(0,o.Lk)("button",{onClick:t[1]||(t[1]=e=>r.goToPage(i.totalPages)),class:(0,l.C4)({active:i.currentPage===i.totalPages}),disabled:i.currentPage===i.totalPages}," 尾页 ",10,se)])):(0,o.Q3)("",!0),(0,o.Lk)("div",ae,[(0,o.Lk)("div",oe,[t[15]||(t[15]=(0,o.Lk)("h2",null,"我要添加课程",-1)),(0,o.Lk)("button",{class:"help-btn",onClick:t[2]||(t[2]=e=>i.showHelp=!0)},t[14]||(t[14]=[(0,o.Lk)("span",{class:"help-icon"},"?",-1),(0,o.eW)(" 帮助 ")]))]),(0,o.Lk)("div",ne,[(0,o.Lk)("div",ie,[t[16]||(t[16]=(0,o.Lk)("label",null,"课程名称",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.newCourseName=e),type:"text",placeholder:"请输入课程名称",class:"modern-input"},null,512),[[a.Jo,i.newCourseName]])]),(0,o.Lk)("div",re,[t[18]||(t[18]=(0,o.Lk)("label",null,"课程类别",-1)),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.newCategoryId=e),class:"modern-select"},t[17]||(t[17]=[(0,o.Fv)('',14)]),512),[[a.u1,i.newCategoryId]])]),(0,o.Lk)("div",ce,[t[20]||(t[20]=(0,o.Lk)("label",null,"开课院系",-1)),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[5]||(t[5]=e=>i.newCollege=e),class:"modern-select"},[t[19]||(t[19]=(0,o.Lk)("option",{value:"",disabled:""},"请选择开课院系",-1)),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.filteredColleges,((e,t)=>((0,o.uX)(),(0,o.CE)("option",{key:t,value:t},(0,l.v_)(e),9,le)))),128))],512),[[a.u1,i.newCollege]])]),(0,o.Lk)("div",ue,[t[21]||(t[21]=(0,o.Lk)("label",null,"任课教师",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[6]||(t[6]=e=>i.newTeachers=e),type:"text",placeholder:"多个教师用英文逗号隔开,如A,B",class:"modern-input"},null,512),[[a.Jo,i.newTeachers]])]),(0,o.Lk)("div",de,[(0,o.Lk)("button",{onClick:t[7]||(t[7]=(...e)=>r.submitCourse&&r.submitCourse(...e)),class:"submit-btn"},"提交课程")])])]),i.showHelp?((0,o.uX)(),(0,o.CE)("div",he,[(0,o.Lk)("div",me,[(0,o.Lk)("div",pe,[t[22]||(t[22]=(0,o.Lk)("h3",null,"关于本系统课程信息的说明",-1)),(0,o.Lk)("button",{class:"close-btn",onClick:t[8]||(t[8]=e=>i.showHelp=!1)},"×")]),t[23]||(t[23]=(0,o.Fv)('

一些说明

本系统中,课程分为两大类:选修课和必修课。选修课有8个小类:通识选修、人文选修、专业方向、体育、学科基础、暑期国际课、数学与自然科学、重修专栏。人文选修类包括采用“抢选”方式进行选课的所有选修课,以及“改革开放史”和“社会主义发展史”两门人文社会科学类的选修课。体育课单独作为一类,不属于人文选修类。重修课程的选课归为选修课的“重修专栏”类别,不属于必修课范畴。重修专栏可以分享任何类别课程,但仅限分享重修体验

必修课有5个小类:数学与自然科学、人文社会科学、学科基础、专业方向、实践。如上所述,本系统中重修的必修课程也属于选修课范畴。特别说明:军训课程属于实践类,系辅导员给分,在创建课程时课程教师请填写辅导员。

在创建课程时,请先了解课程的类别,以及课程的开课院系(详见下文)如果同一课程的任课教师不同,用户可以创建多个同名课程,例如“A老师-篮球”和“B老师-篮球”将被视为两个不同的课程。创建的课程卡片需经过管理员审核,审核进度可在“我的课程”中实时查看。

如何查看课程类别和开课院系?

1. 本人课程

在教务系统选择“我的考试”,选择对应的学期后,即可查看当前学期的课程类别和开课院系。

2. 非本人课程

在教务系统选择“公共课表查询”,课表类型选择“班级课表”,再选好要查询的学期,并填写要查询的班级名称,点击查询按钮。

进入班级课表后,即可对应课程的开课院系。然后记下老师的姓名。

然后回到公共课表查询页面,课表类型选择“教师课表”,同样选好要查询的学期,并填写要查询的教师姓名,点击查询按钮。

进入教师课表后,找到此课程,即可查看课程类别。

',1))])])):(0,o.Q3)("",!0)])}s(4979);var ke={components:{},data(){return{submissions:[],newCourseName:"",newCategoryId:"",newTeachers:"",newCollege:"",currentPage:1,itemsPerPage:10,totalPages:1,isLoaded:!1,cachedEmail:null,showHelp:!1,maxVisiblePages:10,collegeMap:{59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"}}},computed:{paginatedSubmissions(){const e=(this.currentPage-1)*this.itemsPerPage,t=e+this.itemsPerPage;return this.submissions.slice(e,t)},filteredColleges(){return Object.fromEntries(Object.entries(this.collegeMap).filter((([e])=>"59"!==e)))}},mounted(){this.checkMobile(),window.addEventListener("resize",this.checkMobile),setTimeout((async()=>{this.isLoaded=!0,this.fetchSubmissions()}),300),"true"===this.$route.query.m&&(this.showHelp=!0);const e=this.$route.query.c;if(e)try{const t=atob(e);this.isPositiveInteger(t)&&this.$router.push(`/detail/${t}`)}catch(t){}},beforeUnmount(){window.removeEventListener("resize",this.checkMobile)},methods:{checkMobile(){this.maxVisiblePages=window.innerWidth<=768?5:10},isPositiveInteger(e){const t=Number(e);return Number.isInteger(t)&&t>0},async fetchSubmissions(){const e=this.getCookie("token");if(e)try{const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/user/user-submissions",{method:"GET",headers:{"Content-Type":"application/json",Authorization:e}});if(200!==t.status){const e=await t.json();return void alert(e.error||"查询投稿记录失败")}const s=await t.json();this.submissions=s,this.totalPages=Math.ceil(this.submissions.length/this.itemsPerPage)}catch(t){console.error("Fetch submissions error",t)}},getCookie(e){const t=document.cookie.split(";");for(let s of t){const[t,a]=s.trim().split("=");if(t===e)return a}return null},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e)},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,a=this.maxVisiblePages;if(t<=a)for(let o=1;o<=t;o++)e.push(o);else{let o=s-Math.floor(a/2);o=Math.max(o,1);let n=o+a-1;n>t&&(n=t,o=Math.max(n-a+1,1));for(let t=o;t<=n;t++)e.push(t)}return e},async submitCourse(){if(this.newCourseName&&this.newCategoryId&&this.newTeachers&&this.newCollege){if(confirm("确认提交审核吗?")){const e=this.getCookie("token");if(!e)return void alert("无法获取JWT,请重新登录。");const t={course_name:this.newCourseName,category_id:this.newCategoryId,teachers:this.newTeachers,college:this.newCollege};await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/user/submit-course",{method:"POST",headers:{"Content-Type":"application/json",Authorization:e},body:JSON.stringify(t)}),this.newCourseName="",this.newCategoryId="",this.newTeachers="",this.newCollege="",this.fetchSubmissions()}}else alert("请填写所有字段后提交!")},getCategoryName(e){const t={1:"通识选修类",2:"人文选修类",3:"专业方向类",4:"体育类",5:"学科基础类",6:"暑期国际课",7:"数学与自然科学类",8:"重修专栏",9:"必修-数理",10:"必修-人文",11:"必修-学科",12:"必修-专业",13:"必修-实践"};return t[e]||"未知分类"},formatTime(e){const t=new Date(e),s=t.getFullYear(),a=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${a}-${o} ${n}:${i}`},formatTimeShort(e){if(!e)return"-";const t=new Date(e),s=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0");return`${s}-${a}`},handleCardClick(e){0!==e.course_id&&this.$router.push(`/detail/${e.course_id}`)},getStatusClass(e){return"已通过"===e?"status-approved":"待审核"===e?"status-pending":"已拒绝"===e?"status-rejected":""},getCollegeName(e){return this.collegeMap[e]||"未知院系"}}};const ve=(0,C.A)(ke,[["render",ge],["__scopeId","data-v-2964ca48"]]);var Ce=ve;const be={key:0,class:"rating-page"},ye={class:"search-sort-bar card-style"},fe={class:"search-inputs"},Le={class:"input-wrapper"},we={class:"input-wrapper teacher-input"},_e={class:"filters-row"},Se={class:"category-checkboxes"},Ee=["value"],xe={class:"actions-row"},Pe={class:"select-group"},Me=["value"],Te={class:"course-cards"},Ie=["onClick"],Xe={class:"card-header"},je={class:"course-name-title"},$e={key:0,class:"course-tags"},Fe={class:"card-body"},Ne={class:"info-row"},Ae={class:"info-val"},ze={class:"info-row"},We={class:"info-val truncate"},Ue={class:"info-row"},Oe={class:"info-val truncate"},Ve={class:"card-footer"},Re={class:"rating-info"},De={class:"score"},qe={class:"count"},Be={key:0,class:"top-comment"},Qe={key:1,class:"top-comment placeholder"},Je={class:"pagination-bar"},Ke=["onClick"],He=["disabled"],Ge={key:1};function Ye(e,t,s,n,i,r){return i.isLoaded?((0,o.uX)(),(0,o.CE)("div",be,[t[17]||(t[17]=(0,o.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,o.Lk)("div",ye,[(0,o.Lk)("div",fe,[(0,o.Lk)("div",Le,[t[8]||(t[8]=(0,o.Lk)("span",{class:"search-icon"},"🔍",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"搜索课程...",class:"modern-input"},null,512),[[a.Jo,i.searchQuery]])]),(0,o.Lk)("div",we,[t[9]||(t[9]=(0,o.Lk)("span",{class:"search-icon"},"👨‍🏫",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",placeholder:"搜索教师 (如: 张三,李四)",class:"modern-input"},null,512),[[a.Jo,i.teacherQuery]])])]),(0,o.Lk)("div",_e,[(0,o.Lk)("div",Se,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.categories,(e=>((0,o.uX)(),(0,o.CE)("label",{key:e.value,class:"checkbox-label"},[(0,o.bo)((0,o.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:e.value},null,8,Ee),[[a.lH,i.selectedCategories]]),t[10]||(t[10]=(0,o.Lk)("span",{class:"checkmark"},null,-1)),(0,o.eW)(" "+(0,l.v_)(e.label),1)])))),128))])]),(0,o.Lk)("div",xe,[(0,o.Lk)("div",Pe,[(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.sortBy=e),class:"modern-select"},t[11]||(t[11]=[(0,o.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,o.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,o.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[a.u1,i.sortBy]]),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCollege=e),class:"modern-select"},[t[12]||(t[12]=(0,o.Lk)("option",{value:""},"全部院系",-1)),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.filteredColleges,(([e,t])=>((0,o.uX)(),(0,o.CE)("option",{key:e,value:e},(0,l.v_)(t),9,Me)))),128))],512),[[a.u1,i.selectedCollege]])]),(0,o.Lk)("button",{onClick:t[5]||(t[5]=(...e)=>r.searchCourses&&r.searchCourses(...e)),class:"search-btn"}," 更新查询 ")])]),(0,o.Lk)("div",Te,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.courses,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>r.showCourseDetail(e)},[(0,o.Lk)("div",Xe,[(0,o.Lk)("h3",je,(0,l.v_)(e.course_name),1),e.titles&&e.titles.length>0?((0,o.uX)(),(0,o.CE)("div",$e,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(e.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"mini-tag",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128))])):(0,o.Q3)("",!0)]),(0,o.Lk)("div",Fe,[(0,o.Lk)("div",Ne,[t[13]||(t[13]=(0,o.Lk)("span",{class:"info-label"},"分类",-1)),(0,o.Lk)("span",Ae,(0,l.v_)(r.getCategoryName(e.category_id)),1)]),(0,o.Lk)("div",ze,[t[14]||(t[14]=(0,o.Lk)("span",{class:"info-label"},"教师",-1)),(0,o.Lk)("span",We,(0,l.v_)(e.teachers),1)]),(0,o.Lk)("div",Ue,[t[15]||(t[15]=(0,o.Lk)("span",{class:"info-label"},"院系",-1)),(0,o.Lk)("span",Oe,(0,l.v_)(r.getCollegeName(e.college)),1)])]),(0,o.Lk)("div",Ve,[(0,o.Lk)("div",Re,[(0,o.Lk)("span",De,(0,l.v_)(e.rating),1),t[16]||(t[16]=(0,o.Lk)("span",{class:"score-label"},"分",-1)),(0,o.Lk)("span",qe,"("+(0,l.v_)(e.rating_count)+"人)",1)]),e.top_comment?((0,o.uX)(),(0,o.CE)("div",Be,' "'+(0,l.v_)(r.formatTopComment(e.top_comment))+'" ',1)):((0,o.uX)(),(0,o.CE)("div",Qe," 暂无评论 "))])],8,Ie)))),128))]),(0,o.Lk)("div",Je,[(0,o.Lk)("button",{onClick:t[6]||(t[6]=e=>r.goToPage(1)),class:(0,l.C4)({active:1===i.currentPage})},"首页",2),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.getPaginationPages(),(e=>((0,o.uX)(),(0,o.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,l.C4)({active:i.currentPage===e})},(0,l.v_)(e),11,Ke)))),128)),(0,o.Lk)("button",{onClick:t[7]||(t[7]=e=>r.goToPage(i.totalPages)),class:(0,l.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,He)])])):((0,o.uX)(),(0,o.CE)("div",Ge,t[18]||(t[18]=[(0,o.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var Ze={data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],categories:[{label:"通识选修类",value:"1"},{label:"人文选修类",value:"2"},{label:"专业方向类",value:"3"},{label:"体育类",value:"4"},{label:"学科基础类",value:"5"},{label:"暑期国际课",value:"6"},{label:"数学与自然科学类",value:"7"},{label:"重修专栏",value:"8"}],maxVisiblePages:10,collegeMap:{59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"}}},computed:{filteredColleges(){return Object.entries(this.collegeMap).filter((([e])=>"59"!==e))}},mounted(){this.checkMobile(),window.addEventListener("resize",this.checkMobile),setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},beforeUnmount(){window.removeEventListener("resize",this.checkMobile)},methods:{checkMobile(){this.maxVisiblePages=window.innerWidth<=768?5:10},async fetchCourses(){let e="rating-asc"===this.sortBy?"rating":this.sortBy;this.sortOrder="rating-asc"===this.sortBy?"asc":"desc";const t=0===this.selectedCategories.length?"1,2,3,4,5,6,7,8":this.selectedCategories.join(","),s=this.selectedCollege?`&college=${this.selectedCollege}`:"",a=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${a}&teacher=${o}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i.courses,this.currentPage=i.currentPage,this.totalPages=i.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,a=this.maxVisiblePages;if(t<=a)for(let o=1;o<=t;o++)e.push(o);else{let o=s-Math.floor(a/2);o=Math.max(o,1);let n=o+a-1;n>t&&(n=t,o=Math.max(n-a+1,1));for(let t=o;t<=n;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){window.open(`/detail/${e.course_id}`,"_blank")},formatTopComment(e){if(!e)return"";let t=0,s="";for(let a=0;a255?1:.5;if(t+o>29)return s+"...";t+=o,s+=e[a]}return s},getCategoryName(e){const t={1:"通识选修类",2:"人文选修类",3:"专业方向类",4:"体育类",5:"学科基础类",6:"暑期国际课",7:"数学与自然科学类",8:"重修专栏"};return t[e]||"未知分类"},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"}}};const et=(0,C.A)(Ze,[["render",Ye],["__scopeId","data-v-7d8ad36d"]]);var tt=et;const st={key:0,class:"rating-page"},at={class:"search-sort-bar card-style"},ot={class:"search-inputs"},nt={class:"input-wrapper"},it={class:"input-wrapper teacher-input"},rt={class:"filters-row"},ct={class:"category-checkboxes"},lt=["value"],ut={class:"actions-row"},dt={class:"select-group"},ht=["value"],mt={class:"course-cards"},pt=["onClick"],gt={class:"card-header"},kt={class:"course-name-title"},vt={key:0,class:"course-tags"},Ct={class:"card-body"},bt={class:"info-row"},yt={class:"info-val"},ft={class:"info-row"},Lt={class:"info-val truncate"},wt={class:"info-row"},_t={class:"info-val truncate"},St={class:"card-footer"},Et={class:"rating-info"},xt={class:"score"},Pt={class:"count"},Mt={key:0,class:"top-comment"},Tt={key:1,class:"top-comment placeholder"},It={class:"pagination-bar"},Xt=["onClick"],jt=["disabled"],$t={key:1};function Ft(e,t,s,n,i,r){return i.isLoaded?((0,o.uX)(),(0,o.CE)("div",st,[t[17]||(t[17]=(0,o.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,o.Lk)("div",at,[(0,o.Lk)("div",ot,[(0,o.Lk)("div",nt,[t[8]||(t[8]=(0,o.Lk)("span",{class:"search-icon"},"🔍",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"搜索课程...",class:"modern-input"},null,512),[[a.Jo,i.searchQuery]])]),(0,o.Lk)("div",it,[t[9]||(t[9]=(0,o.Lk)("span",{class:"search-icon"},"👨‍🏫",-1)),(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",placeholder:"搜索教师 (如: 张三,李四)",class:"modern-input"},null,512),[[a.Jo,i.teacherQuery]])])]),(0,o.Lk)("div",rt,[(0,o.Lk)("div",ct,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.categories,(e=>((0,o.uX)(),(0,o.CE)("label",{key:e.value,class:"checkbox-label"},[(0,o.bo)((0,o.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:e.value},null,8,lt),[[a.lH,i.selectedCategories]]),t[10]||(t[10]=(0,o.Lk)("span",{class:"checkmark"},null,-1)),(0,o.eW)(" "+(0,l.v_)(e.label),1)])))),128))])]),(0,o.Lk)("div",ut,[(0,o.Lk)("div",dt,[(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.sortBy=e),class:"modern-select"},t[11]||(t[11]=[(0,o.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,o.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,o.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[a.u1,i.sortBy]]),(0,o.bo)((0,o.Lk)("select",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCollege=e),class:"modern-select"},[t[12]||(t[12]=(0,o.Lk)("option",{value:""},"全部院系",-1)),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.filteredColleges,(([e,t])=>((0,o.uX)(),(0,o.CE)("option",{key:e,value:e},(0,l.v_)(t),9,ht)))),128))],512),[[a.u1,i.selectedCollege]])]),(0,o.Lk)("button",{onClick:t[5]||(t[5]=(...e)=>r.searchCourses&&r.searchCourses(...e)),class:"search-btn"}," 更新查询 ")])]),(0,o.Lk)("div",mt,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.courses,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>r.showCourseDetail(e)},[(0,o.Lk)("div",gt,[(0,o.Lk)("h3",kt,(0,l.v_)(e.course_name),1),e.titles&&e.titles.length>0?((0,o.uX)(),(0,o.CE)("div",vt,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(e.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"mini-tag",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128))])):(0,o.Q3)("",!0)]),(0,o.Lk)("div",Ct,[(0,o.Lk)("div",bt,[t[13]||(t[13]=(0,o.Lk)("span",{class:"info-label"},"分类",-1)),(0,o.Lk)("span",yt,(0,l.v_)(r.getCategoryName(e.category_id)),1)]),(0,o.Lk)("div",ft,[t[14]||(t[14]=(0,o.Lk)("span",{class:"info-label"},"教师",-1)),(0,o.Lk)("span",Lt,(0,l.v_)(e.teachers),1)]),(0,o.Lk)("div",wt,[t[15]||(t[15]=(0,o.Lk)("span",{class:"info-label"},"院系",-1)),(0,o.Lk)("span",_t,(0,l.v_)(r.getCollegeName(e.college)),1)])]),(0,o.Lk)("div",St,[(0,o.Lk)("div",Et,[(0,o.Lk)("span",xt,(0,l.v_)(e.rating),1),t[16]||(t[16]=(0,o.Lk)("span",{class:"score-label"},"分",-1)),(0,o.Lk)("span",Pt,"("+(0,l.v_)(e.rating_count)+"人)",1)]),e.top_comment?((0,o.uX)(),(0,o.CE)("div",Mt,' "'+(0,l.v_)(r.formatTopComment(e.top_comment))+'" ',1)):((0,o.uX)(),(0,o.CE)("div",Tt," 暂无评论 "))])],8,pt)))),128))]),(0,o.Lk)("div",It,[(0,o.Lk)("button",{onClick:t[6]||(t[6]=e=>r.goToPage(1)),class:(0,l.C4)({active:1===i.currentPage})},"首页",2),((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(r.getPaginationPages(),(e=>((0,o.uX)(),(0,o.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,l.C4)({active:i.currentPage===e})},(0,l.v_)(e),11,Xt)))),128)),(0,o.Lk)("button",{onClick:t[7]||(t[7]=e=>r.goToPage(i.totalPages)),class:(0,l.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,jt)])])):((0,o.uX)(),(0,o.CE)("div",$t,t[18]||(t[18]=[(0,o.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var Nt={data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],categories:[{label:"数学与自然科学类",value:"9"},{label:"人文社会科学类",value:"10"},{label:"学科基础类",value:"11"},{label:"专业方向类",value:"12"},{label:"实践类",value:"13"}],maxVisiblePages:10,collegeMap:{59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"}}},computed:{filteredColleges(){return Object.entries(this.collegeMap).filter((([e])=>"59"!==e))}},mounted(){this.checkMobile(),window.addEventListener("resize",this.checkMobile),setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},beforeUnmount(){window.removeEventListener("resize",this.checkMobile)},methods:{checkMobile(){this.maxVisiblePages=window.innerWidth<=768?5:10},async fetchCourses(){let e="rating-asc"===this.sortBy?"rating":this.sortBy;this.sortOrder="rating-asc"===this.sortBy?"asc":"desc";const t=0===this.selectedCategories.length?"9,10,11,12,13":this.selectedCategories.join(","),s=this.selectedCollege?`&college=${this.selectedCollege}`:"",a=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${a}&teacher=${o}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i.courses,this.currentPage=i.currentPage,this.totalPages=i.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,a=this.maxVisiblePages;if(t<=a)for(let o=1;o<=t;o++)e.push(o);else{let o=s-Math.floor(a/2);o=Math.max(o,1);let n=o+a-1;n>t&&(n=t,o=Math.max(n-a+1,1));for(let t=o;t<=n;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){this.$router.push(`/detail/${e.course_id}`)},formatTopComment(e){if(!e)return"";let t=0,s="";for(let a=0;a255?1:.5;if(t+o>29)return s+"...";t+=o,s+=e[a]}return s},getCategoryName(e){const t={9:"数学与自然科学类",10:"人文社会科学类",11:"学科基础类",12:"专业方向类",13:"实践类"};return t[e]||"未知分类"},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"}}};const At=(0,C.A)(Nt,[["render",Ft],["__scopeId","data-v-3228e625"]]);var zt=At;const Wt={class:"sidebar"},Ut={class:"header"},Ot={class:"status-text"},Vt={key:0,class:"no-conversations"},Rt=["onClick"],Dt={class:"conversation-name"},qt={key:0,class:"new-message-label"},Bt={class:"conversation-updated-at"},Qt={class:"conversation-last-message"},Jt={class:"chat-container"},Kt={class:"conversation-info"},Ht={class:"message-bubble"},Gt={key:0},Yt={class:"input-container"};function Zt(e,t,s,a,n,i){const r=(0,o.g2)("el-scrollbar"),c=(0,o.g2)("el-button"),u=(0,o.g2)("el-input"),d=(0,o.g2)("el-tooltip"),h=(0,o.g2)("CourseDetailModal");return(0,o.uX)(),(0,o.CE)("div",{class:(0,l.C4)(["chat-page",{"mobile-chat-active":n.activeConversation}])},[(0,o.Lk)("div",Wt,[(0,o.Lk)("h3",Ut,[t[3]||(t[3]=(0,o.eW)(" 会话列表 ")),(0,o.Lk)("span",{class:(0,l.C4)(["connection-status",{connected:n.isConnected,disconnected:!n.isConnected}])},[(0,o.Lk)("span",{class:(0,l.C4)(["status-indicator",{connected:n.isConnected,disconnected:!n.isConnected}])},null,2),(0,o.Lk)("span",Ot,(0,l.v_)(n.isConnected?"即时聊天已连接":"即时聊天已断开,正在重新连接..."),1)],2)]),(0,o.bF)(r,null,{default:(0,o.k6)((()=>[0===n.conversations.length?((0,o.uX)(),(0,o.CE)("div",Vt," 还没有会话,快去通过评论发起聊天吧! ")):((0,o.uX)(!0),(0,o.CE)(o.FK,{key:1},(0,o.pI)(n.conversations,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.conversation_id,class:(0,l.C4)(["conversation-item",e.conversation_id===n.activeConversation?"active":""]),onClick:t=>i.selectConversation(e.conversation_id)},[(0,o.Lk)("div",Dt,[(0,o.eW)((0,l.v_)(e.course_name)+" ",1),(0,o.Lk)("span",{class:(0,l.C4)(["role-label",{owner:"owner"===e.role,member:"member"===e.role}])},(0,l.v_)("owner"===e.role?"我发起的":"我收到的"),3),e.is_read?(0,o.Q3)("",!0):((0,o.uX)(),(0,o.CE)("span",qt,"新消息"))]),(0,o.Lk)("small",Bt,"更新时间: "+(0,l.v_)(i.formatDate(e.updated_at)),1),t[4]||(t[4]=(0,o.Lk)("br",null,null,-1)),(0,o.Lk)("small",Qt,(0,l.v_)(e.latest_sender?"我:":"对方:")+(0,l.v_)(e.content||"还没有消息哦,快去通过某条课程评论发起聊天吧!"),1)],10,Rt)))),128))])),_:1})]),(0,o.Lk)("div",Jt,[(0,o.Lk)("div",Kt,[(0,o.Lk)("button",{class:"mobile-back-btn",onClick:t[0]||(t[0]=e=>n.activeConversation=null)}," < 返回 "),(0,o.Lk)("span",null,(0,l.v_)(null!==n.rating?"该用户对课程评分为 "+n.rating.toFixed(1):"该用户暂未对课程进行评分"),1),(0,o.bF)(c,{onClick:t[1]||(t[1]=e=>n.selectedCourseId&&i.loadCourseDetail(n.selectedCourseId))},{default:(0,o.k6)((()=>t[5]||(t[5]=[(0,o.eW)("查看课程")]))),_:1})]),(0,o.bF)(r,{ref:"messageScrollbar",class:"message-list"},{default:(0,o.k6)((()=>[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(n.messages,((e,t)=>((0,o.uX)(),(0,o.CE)("div",{key:t,class:(0,l.C4)(["message",1===e.sender?"self":"other"])},[(0,o.Lk)("div",Ht,[(0,o.Lk)("span",null,(0,l.v_)(e.content),1),(0,o.Lk)("div",{class:(0,l.C4)(["message-info",1===e.sender?"align-right":"align-left"])},[(0,o.Lk)("small",null,(0,l.v_)(i.formatDate(e.created_at)),1),1===e.sender?((0,o.uX)(),(0,o.CE)("small",Gt,(0,l.v_)(e.is_read?"已读":"未读"),1)):(0,o.Q3)("",!0)],2)])],2)))),128))])),_:1},512),(0,o.Lk)("div",Yt,[(0,o.bF)(u,{modelValue:n.newMessage,"onUpdate:modelValue":t[2]||(t[2]=e=>n.newMessage=e),type:"textarea",rows:"2",placeholder:"请输入您的消息,按Enter换行,Ctrl+Enter发送。",class:"locked-input",onKeydown:i.handleKeyDown},null,8,["modelValue","onKeydown"]),(0,o.bF)(d,{content:"Ctrl + Enter",placement:"top"},{default:(0,o.k6)((()=>[(0,o.bF)(c,{onClick:i.sendMessage,type:"primary"},{default:(0,o.k6)((()=>t[6]||(t[6]=[(0,o.eW)("发送")]))),_:1},8,["onClick"])])),_:1})])]),n.selectedCourse?((0,o.uX)(),(0,o.Wv)(h,{key:0,isVisible:n.showDetail,course:n.selectedCourse,onClose:i.closeCourseDetail},null,8,["isVisible","course","onClose"])):(0,o.Q3)("",!0)],2)}var es=s(4373);const ts={key:0,class:"modal-overlay"},ss={class:"modal-content"},as={key:0,class:"loading"},os={key:1,class:"course-detail"},ns={key:0,class:"share-modal"},is={key:1,class:"error-modal"},rs={class:"rating-section"},cs={class:"total-rating"},ls={class:"progress-container"},us={class:"stars"},ds=["onMouseover","onClick"],hs={class:"ai-summary"},ms={key:0,class:"typing-cursor"},ps={class:"comment-section"},gs={class:"sort-options"},ks={key:0,class:"comments-list"},vs={class:"comment-meta"},Cs={class:"comment-time",style:{"margin-left":"10px"}},bs=["onClick"],ys={style:{"margin-top":"8px"}},fs={class:"comment-actions"},Ls={style:{color:"red"}},ws=["onClick"],_s=["onClick"],Ss={key:1,class:"no-comments"},Es={key:2,class:"chat-modal-overlay"},xs={class:"chat-modal-content"},Ps={class:"chat-modal-actions"},Ms=["disabled"],Ts={key:3,class:"chat-modal-overlay"},Is={class:"chat-modal-content"},Xs={class:"chat-modal-actions"},js={class:"new-comment"};function $s(e,t,s,n,i,r){const c=(0,o.g2)("el-progress");return s.isVisible?((0,o.uX)(),(0,o.CE)("div",ts,[(0,o.Lk)("div",ss,[(0,o.Lk)("span",{class:"close",onClick:t[0]||(t[0]=(...e)=>r.closeModal&&r.closeModal(...e))},"×"),i.loading?((0,o.uX)(),(0,o.CE)("div",as,t[16]||(t[16]=[(0,o.Lk)("p",null,"加载中...",-1)]))):(0,o.Q3)("",!0),!i.loading&&i.course&&i.course.course_id?((0,o.uX)(),(0,o.CE)("div",os,[(0,o.Lk)("h3",null,[(0,o.eW)((0,l.v_)(i.course.course_name)+" ",1),i.course.titles&&i.course.titles.length>0?((0,o.uX)(!0),(0,o.CE)(o.FK,{key:0},(0,o.pI)(i.course.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"course-title",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128)):(0,o.Q3)("",!0),(0,o.Lk)("button",{class:"share-btn",onClick:t[1]||(t[1]=(...e)=>r.shareCourse&&r.shareCourse(...e))},"分享给好友")]),(0,o.Lk)("p",null,[t[17]||(t[17]=(0,o.Lk)("strong",null,"分类:",-1)),(0,o.eW)(" "+(0,l.v_)(r.getCategoryName(i.course.category_id)),1)]),(0,o.Lk)("p",null,[t[18]||(t[18]=(0,o.Lk)("strong",null,"教师:",-1)),(0,o.eW)(" "+(0,l.v_)(i.course.teachers),1)]),(0,o.Lk)("p",null,[t[19]||(t[19]=(0,o.Lk)("strong",null,"开课院系:",-1)),(0,o.eW)(" "+(0,l.v_)(r.getCollegeName(i.course.college)),1)]),i.showShareModal?((0,o.uX)(),(0,o.CE)("div",ns," 链接复制成功,快去分享给其他小伙伴吧! ")):(0,o.Q3)("",!0),i.showErrorModal?((0,o.uX)(),(0,o.CE)("div",is," 获取评论数据失败,正在刷新页面... ")):(0,o.Q3)("",!0),(0,o.Lk)("div",rs,[(0,o.Lk)("h4",null,"课程实时平均分 ("+(0,l.v_)(i.course.rating_count)+"人评分)",1),(0,o.Lk)("div",cs,(0,l.v_)(i.totalRating),1),(0,o.Lk)("div",ls,[(0,o.bF)(c,{class:"progress",percentage:i.fiveStarPercent,status:"success","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("5星: "+(0,l.v_)(i.fiveStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.fourStarPercent,status:"success","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("4星: "+(0,l.v_)(i.fourStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.threeStarPercent,status:"warning","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("3星: "+(0,l.v_)(i.threeStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.twoStarPercent,status:"warning","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("2星: "+(0,l.v_)(i.twoStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,o.bF)(c,{class:"progress",percentage:i.oneStarPercent,status:"exception","text-inside":""},{default:(0,o.k6)((()=>[(0,o.eW)("1星: "+(0,l.v_)(i.oneStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"])]),(0,o.Lk)("div",us,[((0,o.uX)(),(0,o.CE)(o.FK,null,(0,o.pI)(5,(e=>(0,o.Lk)("span",{key:e,class:(0,l.C4)({highlighted:e<=i.userRating}),onMouseover:t=>r.highlightStars(e),onMouseout:t[2]||(t[2]=(...e)=>r.resetStars&&r.resetStars(...e)),onClick:t=>r.confirmRating(e)}," ★ ",42,ds))),64))])]),(0,o.Lk)("p",hs,[t[20]||(t[20]=(0,o.Lk)("span",{style:{display:"block","margin-bottom":"-15px"}},[(0,o.Lk)("strong",null,"AI课程总结"),(0,o.Lk)("span",{style:{color:"white","font-size":"8px","margin-left":"5px","border-radius":"4px",padding:"1px 4px","background-color":"red","vertical-align":"super"}},"Beta"),(0,o.Lk)("span",{style:{"font-size":"12px","margin-left":"5px"}},[(0,o.eW)(" 内容由 "),(0,o.Lk)("img",{src:"https://download.东北大学.com/course_system/deepseek.svg",style:{height:"16px","vertical-align":"middle"}}),(0,o.eW)(" DeepSeek V3 生成,仅供参考 ")])],-1)),t[21]||(t[21]=(0,o.Lk)("br",null,null,-1)),i.displayedSummary?((0,o.uX)(),(0,o.CE)(o.FK,{key:0},[(0,o.eW)((0,l.v_)(i.displayedSummary),1),i.isTyping?((0,o.uX)(),(0,o.CE)("span",ms,"|")):(0,o.Q3)("",!0)],64)):((0,o.uX)(),(0,o.CE)(o.FK,{key:1},[(0,o.eW)(" 当前课程的评分和评论数据过少,暂不能生成AI总结。 ")],64))])])):(0,o.Q3)("",!0),(0,o.Lk)("div",ps,[(0,o.Lk)("div",gs,[(0,o.Lk)("label",null,[(0,o.bo)((0,o.Lk)("input",{type:"radio",value:"like_count","onUpdate:modelValue":t[3]||(t[3]=e=>i.sortBy=e),onChange:t[4]||(t[4]=(...e)=>r.fetchComments&&r.fetchComments(...e))},null,544),[[a.XL,i.sortBy]]),t[22]||(t[22]=(0,o.eW)(" 赞数最多优先"))]),(0,o.Lk)("label",null,[(0,o.bo)((0,o.Lk)("input",{type:"radio",value:"comment_time","onUpdate:modelValue":t[5]||(t[5]=e=>i.sortBy=e),onChange:t[6]||(t[6]=(...e)=>r.fetchComments&&r.fetchComments(...e))},null,544),[[a.XL,i.sortBy]]),t[23]||(t[23]=(0,o.eW)(" 最新评论优先"))])]),r.filteredComments?((0,o.uX)(),(0,o.CE)("div",ks,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.comments,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.comment_id,class:"comment"},[(0,o.Lk)("div",vs,[(0,o.Lk)("strong",null,(0,l.v_)(e.nickname),1),(0,o.Lk)("span",Cs,"发表于 "+(0,l.v_)(r.formatTime(e.comment_time)),1),(0,o.Lk)("span",{class:(0,l.C4)(["like-section",{liked:e.is_liked}]),onClick:t=>r.toggleLike(e)}," ❤ "+(0,l.v_)(e.like_count),11,bs)]),(0,o.Lk)("div",ys,(0,l.v_)(e.comment_content),1),(0,o.Lk)("div",fs,[(0,o.Lk)("span",null,[t[24]||(t[24]=(0,o.eW)("评分: ")),(0,o.Lk)("strong",Ls,(0,l.v_)(e.rating),1)]),e.deleteable?((0,o.uX)(),(0,o.CE)("button",{key:0,onClick:t=>r.deleteComment(e.comment_id),class:"delete-btn"}," 删除 ",8,ws)):((0,o.uX)(),(0,o.CE)("button",{key:1,class:"chat-start-btn",onClick:t=>r.openChatModal(e.comment_id)}," 发起聊天 ",8,_s))])])))),128))])):((0,o.uX)(),(0,o.CE)("p",Ss,"本课程暂无评论。")),i.isChatModalVisible?((0,o.uX)(),(0,o.CE)("div",Es,[(0,o.Lk)("div",xs,[(0,o.Lk)("span",{class:"chat-close-btn",onClick:t[7]||(t[7]=(...e)=>r.closeChatModal&&r.closeChatModal(...e))},"×"),t[25]||(t[25]=(0,o.Lk)("h3",null,"发起聊天",-1)),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.chatMessage=e),placeholder:"请输入聊天内容(至少6个字符)",class:"chat-textarea"},null,512),[[a.Jo,i.chatMessage]]),(0,o.Lk)("div",Ps,[(0,o.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>r.submitChat&&r.submitChat(...e)),disabled:i.chatMessage.length<6},"发起",8,Ms)])])])):(0,o.Q3)("",!0),i.isConversationExistsModalVisible?((0,o.uX)(),(0,o.CE)("div",Ts,[(0,o.Lk)("div",Is,[(0,o.Lk)("span",{class:"chat-close-btn",onClick:t[10]||(t[10]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"×"),t[26]||(t[26]=(0,o.Lk)("h3",null,"在此课程下,您与此用户已有会话!",-1)),(0,o.Lk)("div",Xs,[(0,o.Lk)("button",{onClick:t[11]||(t[11]=e=>r.navigateToConversation(i.existingConversationId))},"进入会话"),(0,o.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"取消")])])])):(0,o.Q3)("",!0),(0,o.Lk)("div",js,[(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[13]||(t[13]=e=>i.nickname=e),placeholder:"一句话概括您的评论,如:被x老师伤透了心"},null,512),[[a.Jo,i.nickname]]),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[14]||(t[14]=e=>i.commentContent=e),placeholder:"我们推荐您分享本课程的课程内容、学习难度、考核方式和给分好坏,以帮助更多同学做出判断。支持删除自己的评论。",style:{resize:"none",height:"50px"}},null,512),[[a.Jo,i.commentContent]]),(0,o.Lk)("button",{onClick:t[15]||(t[15]=(...e)=>r.submitComment&&r.submitComment(...e))},"提交评论")])])])])):(0,o.Q3)("",!0)}var Fs={props:{isVisible:{type:Boolean,required:!0},courseId:{type:[Number,String],required:!0}},data(){return{loading:!1,course:{},token:null,userRating:0,totalRating:0,fiveStarPercent:0,fourStarPercent:0,threeStarPercent:0,twoStarPercent:0,oneStarPercent:0,comments:[],nickname:"",commentContent:"",sortBy:"like_count",showShareModal:!1,cachedEmail:null,isChatModalVisible:!1,isConversationExistsModalVisible:!1,chatMessage:"",currentCommentId:null,existingConversationId:null,showErrorModal:!1,aiSummary:null,displayedSummary:"",isTyping:!1,shouldStopTyping:!1}},watch:{courseId:{immediate:!0,handler(e){e&&this.isVisible&&this.loadCourseData()}},isVisible(e){e&&this.courseId&&this.loadCourseData()},displayedSummary(){this.isTyping&&this.$nextTick((()=>{const e=document.querySelector(".course-detail");e&&(e.scrollTop=e.scrollHeight)}))}},computed:{filteredComments(){return this.comments.length>0?this.comments:null}},methods:{async loadCourseData(){if(this.courseId){this.loading=!0,this.course={},this.aiSummary=null,this.displayedSummary="",this.isTyping=!1,this.shouldStopTyping=!1;try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/course-detail?course_id=${this.courseId}`);if(!e.ok)throw new Error("Failed to fetch course detail");this.course=await e.json(),this.getToken(),await Promise.all([this.fetchAndCacheEmail(),this.fetchRatingDistribution(),this.fetchUserRating(),this.fetchComments(),this.fetchAISummary()])}catch(e){console.error("Error loading course data:",e)}finally{this.loading=!1}}},getToken(){const e=document.cookie.split("; ").find((e=>e.startsWith("token=")));e?this.token=e.split("=")[1]:(console.error("Token not found in cookies"),this.token=null)},closeModal(){this.shouldStopTyping=!0,this.isTyping=!1,this.displayedSummary="",this.aiSummary=null,this.$emit("close")},getCategoryName(e){const t={1:"选修课-通识选修类",2:"选修课-人文选修类",3:"选修课-专业方向类",4:"选修课-体育类",5:"选修课-学科基础类",6:"选修课-暑期国际课",7:"选修课-数学与自然科学类",8:"选修课-重修专栏",9:"必修课-数学与自然科学类",10:"必修课-人文社会科学类",11:"必修课-学科基础类",12:"必修课-专业方向类",13:"必修课-实践类"};return t[e]||"未知分类"},async fetchRatingDistribution(){const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-course-ratings-distribution?course_id=${this.course.course_id}`);if(e.ok){const t=await e.json();this.totalRating=t.total_rating||0,this.fiveStarPercent=100*t.five_stars,this.fourStarPercent=100*t.four_stars,this.threeStarPercent=100*t.three_stars,this.twoStarPercent=100*t.two_stars,this.oneStarPercent=100*t.one_star}else 404===e.status&&(this.totalRating=0,this.fiveStarPercent=0,this.fourStarPercent=0,this.threeStarPercent=0,this.twoStarPercent=0,this.oneStarPercent=0)},async fetchUserRating(){const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-user-rating?course_id=${this.course.course_id}`,{headers:{Authorization:this.token}});if(200===e.status){const t=await e.json();this.userRating=t.rating}else this.userRating=0},highlightStars(e){this.userRating=e},resetStars(){this.fetchUserRating()},confirmRating(e){confirm(`您确定要给课程 "${this.course.course_name}" 评分:${e}.0 吗?如您之前有评分记录,此评分将覆盖之前的评分。`)&&this.submitRating(e)},async submitRating(e){const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-rating",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.course.course_id,rating:e})});t.ok&&(this.fetchRatingDistribution(),this.fetchUserRating())},async typewriterEffect(e,t=10){this.isTyping=!0,this.displayedSummary="",this.shouldStopTyping=!1;for(let s=0;ssetTimeout(e,t)))}this.isTyping=!1},async fetchAISummary(){try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/ai_summary/summary?course_id=${this.course.course_id}`);if(!e.ok){if(404===e.status)return this.aiSummary=null,void(this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。");throw new Error("获取AI总结失败")}const t=await e.json();t.summary?(this.aiSummary=t.summary,await this.typewriterEffect(this.aiSummary)):this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。"}catch(e){console.error("生成AI总结失败:",e),this.displayedSummary="生成AI总结时出错,请稍后再试。"}},async fetchComments(){try{if(!this.token)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-comments?course_id=${this.course.course_id}&sort_by=${this.sortBy}`,{headers:{Authorization:this.token}});if(403===e.status)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);if(404===e.status)return void(this.comments=[]);if(!e.ok)throw new Error("获取评论失败");const t=await e.json();this.comments=t.comments}catch(e){console.error("获取评论失败:",e),this.showErrorModal=!0,setTimeout((()=>{window.location.reload()}),2e3)}},async toggleLike(e){e.is_liked?await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/unlike-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e.comment_id})}):await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/like-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e.comment_id})}),this.fetchComments()},async submitComment(){this.nickname.length<3||this.commentContent.length<6?alert("您的昵称请至少包含3个字符,评论请至少包含6个字符。"):(await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.course.course_id,nickname:this.nickname,comment_content:this.commentContent})}),this.fetchComments(),this.nickname="",this.commentContent="")},formatTime(e){const t=new Date(e),s=t.getFullYear(),a=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${a}-${o} ${n}:${i}`},async fetchAndCacheEmail(){if(!this.cachedEmail)if(this.token)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token}}),t=await e.json();e.ok&&t.email?this.cachedEmail=t.email:console.error("JWT验证失败或未找到邮箱")}catch(e){console.error("JWT验证时出错:",e)}else console.error("未找到JWT信息")},getUserEmailFromCookie(){return this.cachedEmail?this.cachedEmail:(console.error("邮箱尚未缓存"),"")},base64Encode(e){return btoa(e)},shareCourse(){const e=this.course.course_name,t=this.base64Encode(this.course.course_id.toString());let s="";s=0!==this.totalRating?`我在NEU小站为课程【${e}】评分,当前评分【${this.totalRating}】,点击【https://course.xn--xhq44jb2fzpc.com/courses?c=${t}】加入评分吧!`:`我在NEU小站为课程【${e}】评分,点击【https://course.xn--xhq44jb2fzpc.com/courses?c=${t}】加入评分吧!`,this.copyToClipboard(s),this.showShareModal=!0,setTimeout((()=>{this.showShareModal=!1}),3e3)},copyToClipboard(e){const t=document.createElement("textarea");t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"},openChatModal(e){this.currentCommentId=e,this.chatMessage="",this.isChatModalVisible=!0},closeChatModal(){this.isChatModalVisible=!1},closeConversationExistsModal(){this.isConversationExistsModalVisible=!1},async submitChat(){if(this.chatMessage.length<6)alert("聊天内容需至少6个字符");else try{const e=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/chat/start-conversation",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:this.currentCommentId,content:this.chatMessage})}),t=await e.json();e.ok&&"Conversation started successfully"===t.message?this.$router.push(`/chat?mid=${t.conversation_id}`):e.ok&&"Conversation already exists"===t.message?(this.existingConversationId=t.conversation_id,this.isConversationExistsModalVisible=!0):"Recipient account status is abnormal, cannot create a conversation"===t.error?alert("此账号状态异常,暂时无法发起聊天!"):"Cannot start a conversation with yourself!"===t.error?alert("不能向自己发起聊天!"):alert("发起会话失败,请稍后再试")}catch(e){console.error("Error starting conversation:",e),alert("发起会话失败,请稍后再试")}finally{this.closeChatModal()}},navigateToConversation(e){this.$router.push(`/chat?mid=${e}`),this.closeConversationExistsModal()},async deleteComment(e){const t=confirm("确定删除评论吗?");if(t)try{const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/delete-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e})});if(t.ok)this.fetchComments();else{const e=await t.json();alert(e.error||"删除评论失败")}}catch(s){console.error("删除评论出错:",s),alert("删除评论失败")}}}};const Ns=(0,C.A)(Fs,[["render",$s],["__scopeId","data-v-9c153036"]]);var As=Ns,zs={components:{CourseDetailModal:As},data(){return{userId:"",activeConversation:null,conversations:[],messages:[],newMessage:"",socket:null,rating:null,selectedCourse:null,selectedCourseId:0,showDetail:!1,isConnected:!1}},async activated(){await this.fetchConversations(),this.activeConversation&&await this.selectConversation(this.activeConversation)},async mounted(){try{const e=this.getCookie("token");if(!e)throw new Error("JWT not found in cookies");const t=JSON.parse(atob(e.split(".")[1]));this.userId=t.id,await this.fetchConversations(),this.checkAndSwitchConversation(),this.initializeWebSocket()}catch(e){console.error("Failed to initialize chat page:",e.message)}},beforeUnmount(){this.socket&&this.socket.close()},methods:{async fetchConversations(){try{const e=await es.A.get("/chat/conversations",{headers:{Authorization:this.getCookie("token")}});this.conversations=[...e.data.conversations]}catch(e){console.error("Failed to fetch conversations:",e)}},formatDate(e){const t=new Date(e);return t.toLocaleString()},async loadCourseDetail(e){try{const t=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/course-detail?course_id=${e}`),s=await t.json();this.selectedCourse=s,this.showDetail=!0}catch(t){console.error("Error loading course details:",t)}},closeCourseDetail(){this.showDetail=!1,this.selectedCourse=null},initializeWebSocket(){const e=this.getCookie("token");if(!e)return void console.error("WebSocket initialization failed: No token found");const t=`${"https:"===window.location.protocol?"wss://coursesystem.xn--xhq44jb2fzpc.com":"ws://49.232.202.164:8080"}/chat?token=${e}`;console.log(`Attempting to connect to WebSocket at: ${t}`),this.socket=new WebSocket(t),this.socket.onopen=()=>{this.isConnected=!0,console.log("WebSocket connected")},this.socket.onmessage=async e=>{try{const t=JSON.parse(e.data);switch(console.log("Received WebSocket message:",t),t.type){case"new_conversation":await this.fetchConversations(),t.conversation_id===this.activeConversation&&await this.selectConversation(t.conversation_id);break;case"new_message":await this.fetchConversations(),t.conversation_id===this.activeConversation&&await this.selectConversation(t.conversation_id);break;case"message_read":if(t.conversation_id===this.activeConversation){const e=this.messages.findIndex((e=>e.message_id===t.message_id&&1===e.sender));-1!==e&&this.$set(this.messages[e],"is_read",!0)}break;case"conversation_read":t.conversation_id===this.activeConversation&&this.messages.forEach((e=>{1===e.sender&&t.message_ids.includes(e.message_id)&&(e.is_read=!0)}));break;default:console.warn(`Unknown WebSocket message type: ${t.type}`)}}catch(t){console.error("Error processing WebSocket message:",t)}},this.socket.onclose=e=>{this.isConnected=!1,console.warn(`WebSocket disconnected: Code ${e.code}, Reason: ${e.reason}`),this.reconnectWebSocket()},this.socket.onerror=e=>{console.error("WebSocket error:",e)}},reconnectWebSocket(){console.warn("Attempting to reconnect WebSocket..."),setTimeout((async()=>{try{this.initializeWebSocket();const e=new Promise(((e,t)=>{const s=setInterval((()=>{this.socket&&this.socket.readyState===WebSocket.OPEN&&(clearInterval(s),e())}),500);setTimeout((()=>{clearInterval(s),t(new Error("WebSocket reconnect timeout"))}),1e4)}));await e,this.isConnected=!0,console.log("WebSocket reconnected successfully"),await this.fetchConversations(),this.activeConversation&&await this.selectConversation(this.activeConversation)}catch(e){console.error("Failed to reconnect WebSocket:",e)}}),5e3)},async selectConversation(e){this.activeConversation=e;try{const t=this.conversations.find((t=>t.conversation_id===e));if(!t)throw new Error("Conversation not found");this.selectedCourseId=t.course_id;const s=await es.A.get("/chat/conversation-messages",{params:{conversation_id:e,course_name:t.course_name},headers:{Authorization:this.getCookie("token")}});this.messages=[...s.data.messages],this.rating=s.data.rating||null,this.$nextTick((()=>{this.scrollToBottom()})),await this.markMessagesAsRead()}catch(t){console.error("Failed to fetch conversation messages:",t)}},async markMessagesAsRead(){try{await es.A.post("/chat/read-conversation",{conversation_id:this.activeConversation},{headers:{Authorization:this.getCookie("token")}}),this.messages.forEach((e=>{0!==e.sender||e.is_read||(e.is_read=!0)}))}catch(e){console.error("Failed to mark messages as read:",e)}},async sendMessage(){if(!this.newMessage.trim())return;const e=this.newMessage;this.newMessage="";try{const t=await es.A.post("/chat/send-message",{conversation_id:this.activeConversation,content:e},{headers:{Authorization:this.getCookie("token")}});this.messages.push({message_id:t.data.message_id,content:e,sender:1,created_at:(new Date).toISOString(),is_read:!1}),this.$nextTick((()=>{this.scrollToBottom()})),await this.markMessagesAsRead(),await this.fetchConversations()}catch(t){console.error("Failed to send message:",t)}},scrollToBottom(){setTimeout((()=>{const e=this.$refs.messageScrollbar;if(e){const t=e.$el.querySelector(".el-scrollbar__wrap");t&&(t.scrollTop=t.scrollHeight)}}),50)},handleKeyDown(e){e.ctrlKey&&"Enter"===e.key&&this.sendMessage()},getCookie(e){const t=document.cookie.split("; ");for(let s=0;se.conversation_id===t));s?await this.selectConversation(t):console.warn("Conversation not found for ID:",t)}}};const Ws=(0,C.A)(zs,[["render",Zt],["__scopeId","data-v-38851032"]]);var Us=Ws;const Os={class:"about-container"},Vs={class:"about-page"},Rs={class:"version-timeline"};function Ds(e,t){const s=(0,o.g2)("el-timeline-item"),a=(0,o.g2)("el-timeline");return(0,o.uX)(),(0,o.CE)("div",Os,[(0,o.Lk)("div",Vs,[t[6]||(t[6]=(0,o.Lk)("div",{class:"project-intro"},[(0,o.Lk)("h2",null,"关于本项目"),(0,o.Lk)("div",{class:"intro-content"},[(0,o.Lk)("p",null,"NEU小站课程评分系统是专门为东北大学学生设计的课程评价平台。本系统采用全匿名方式,学生可以匿名对课程进行评分和发表评论,帮助其他同学更好地了解课程信息。"),(0,o.Lk)("p",null,"系统支持选修课和必修课的评分,包括通识选修、人文选修、专业方向等多个类别。为了保护用户隐私,发表评论时不会显示用户在NEU小站的用户名,每次评论的昵称均由用户自行定义。"),(0,o.Lk)("p",null,"本系统仅对完成NEU小站校园认证的用户开放,确保信息的真实性和可靠性。未来本系统还计划为校内用户开放评分数据下载。")])],-1)),(0,o.Lk)("div",Rs,[t[5]||(t[5]=(0,o.Lk)("h2",null,"更新日志",-1)),(0,o.bF)(a,null,{default:(0,o.k6)((()=>[(0,o.bF)(s,{timestamp:"2025年12月",placement:"top"},{default:(0,o.k6)((()=>t[0]||(t[0]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v2.0"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"重构响应式UI,优化移动端用户体验。暂时下线聊天功能。")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2025年2月",placement:"top"},{default:(0,o.k6)((()=>t[1]||(t[1]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.4"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"优化页面样式和用户体验")])],-1),(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.3"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"新增AI课程总结功能,接入DeepSeek V3大模型")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2025年1月",placement:"top"},{default:(0,o.k6)((()=>t[2]||(t[2]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.2"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"评论区支持删除自己的评论"),(0,o.Lk)("li",null,'优化了"评分由低到高"排序的逻辑,会先展示有评分(评分不为0)的课程'),(0,o.Lk)("li",null,"新增了2024-2025学年春季学期的140门通识选修课")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2024年11月",placement:"top"},{default:(0,o.k6)((()=>t[3]||(t[3]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.1.0"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"新增在线聊天功能"),(0,o.Lk)("li",null,"支持从评论发起聊天")])],-1)]))),_:1}),(0,o.bF)(s,{timestamp:"2024年9月",placement:"top"},{default:(0,o.k6)((()=>t[4]||(t[4]=[(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.0.2"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"新增必修课评分功能"),(0,o.Lk)("li",null,"增加课程类别"),(0,o.Lk)("li",null,"更新用户验证相关接口,增强安全性"),(0,o.Lk)("li",null,"修复部分Bug")])],-1),(0,o.Lk)("div",{class:"version-item"},[(0,o.Lk)("h4",null,"v1.0.0"),(0,o.Lk)("ul",null,[(0,o.Lk)("li",null,"课程评分系统正式上线(测试版)")])],-1)]))),_:1})])),_:1})])])])}const qs={},Bs=(0,C.A)(qs,[["render",Ds],["__scopeId","data-v-5c1b02c2"]]);var Qs=Bs;const Js={class:"course-detail-page"},Ks={key:0,class:"loading-state"},Hs={key:1,class:"container"},Gs={class:"top-section"},Ys={class:"info-card card"},Zs={class:"card-header"},ea={class:"course-name"},ta={key:0,class:"tags"},sa={class:"info-grid"},aa={class:"info-item"},oa={class:"value"},na={class:"info-item"},ia={class:"value"},ra={class:"info-item full-width"},ca={class:"value"},la={class:"action-area"},ua={class:"rating-card card"},da={class:"rating-overview"},ha={class:"total-score"},ma={class:"score"},pa={class:"count"},ga={class:"user-rating-action"},ka={class:"stars interactive"},va=["onMouseover","onClick"],Ca={class:"rating-bars"},ba={class:"bar-row"},ya={class:"percent"},fa={class:"bar-row"},La={class:"percent"},wa={class:"bar-row"},_a={class:"percent"},Sa={class:"bar-row"},Ea={class:"percent"},xa={class:"bar-row"},Pa={class:"percent"},Ma={class:"ai-section card"},Ta={class:"ai-content"},Ia={key:0,class:"summary-text"},Xa={key:0,class:"cursor"},ja={key:1,class:"empty-text"},$a={class:"comments-section card"},Fa={class:"section-header"},Na={class:"sort-tabs"},Aa={class:"post-comment"},za={class:"input-group"},Wa={key:0,class:"comments-list"},Ua={class:"comment-header"},Oa={class:"comment-author"},Va={class:"comment-date"},Ra={class:"comment-body"},Da={class:"comment-footer"},qa={class:"rating-tag"},Ba={class:"actions"},Qa=["onClick"],Ja=["onClick"],Ka={key:1,class:"no-comments"},Ha={key:0,class:"toast"},Ga={key:0,class:"toast error"},Ya={key:2,class:"modal-overlay"},Za={class:"modal-box"},eo={class:"modal-actions"},to=["disabled"],so={key:3,class:"modal-overlay"},ao={class:"modal-box"},oo={class:"modal-actions"};function no(e,t,s,n,i,r){const c=(0,o.g2)("el-progress");return(0,o.uX)(),(0,o.CE)("div",Js,[i.loading?((0,o.uX)(),(0,o.CE)("div",Ks,t[13]||(t[13]=[(0,o.Lk)("div",{class:"spinner"},null,-1),(0,o.Lk)("p",null,"正在加载课程详情...",-1)]))):((0,o.uX)(),(0,o.CE)("div",Hs,[(0,o.Lk)("div",Gs,[(0,o.Lk)("div",Ys,[(0,o.Lk)("div",Zs,[(0,o.Lk)("h1",ea,[(0,o.eW)((0,l.v_)(i.course.course_name)+" ",1),i.course.titles&&i.course.titles.length>0?((0,o.uX)(),(0,o.CE)("div",ta,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.course.titles,(e=>((0,o.uX)(),(0,o.CE)("span",{key:e.title,class:"tag",style:(0,l.Tr)({borderColor:e.color,color:e.color})},(0,l.v_)(e.title),5)))),128))])):(0,o.Q3)("",!0)])]),(0,o.Lk)("div",sa,[(0,o.Lk)("div",aa,[t[14]||(t[14]=(0,o.Lk)("span",{class:"label"},"分类",-1)),(0,o.Lk)("span",oa,(0,l.v_)(r.getCategoryName(i.course.category_id)),1)]),(0,o.Lk)("div",na,[t[15]||(t[15]=(0,o.Lk)("span",{class:"label"},"开课院系",-1)),(0,o.Lk)("span",ia,(0,l.v_)(r.getCollegeName(i.course.college)),1)]),(0,o.Lk)("div",ra,[t[16]||(t[16]=(0,o.Lk)("span",{class:"label"},"教师(团队)",-1)),(0,o.Lk)("span",ca,(0,l.v_)(i.course.teachers),1)])]),(0,o.Lk)("div",la,[(0,o.Lk)("button",{class:"share-btn",onClick:t[0]||(t[0]=(...e)=>r.shareCourse&&r.shareCourse(...e))},t[17]||(t[17]=[(0,o.Lk)("span",{class:"icon"},"🔗",-1),(0,o.eW)(" 复制链接 ")]))])]),(0,o.Lk)("div",ua,[t[24]||(t[24]=(0,o.Lk)("h3",null,"课程评分",-1)),(0,o.Lk)("div",da,[(0,o.Lk)("div",ha,[(0,o.Lk)("span",ma,(0,l.v_)(i.totalRating),1),(0,o.Lk)("span",pa,"("+(0,l.v_)(i.course.rating_count||0)+"人评分)",1)]),(0,o.Lk)("div",ga,[t[18]||(t[18]=(0,o.Lk)("p",null,"您的评分",-1)),(0,o.Lk)("div",ka,[((0,o.uX)(),(0,o.CE)(o.FK,null,(0,o.pI)(5,(e=>(0,o.Lk)("span",{key:e,class:(0,l.C4)({active:e<=i.userRating}),onMouseover:t=>r.highlightStars(e),onMouseout:t[1]||(t[1]=(...e)=>r.resetStars&&r.resetStars(...e)),onClick:t=>r.confirmRating(e)},"★",42,va))),64))])])]),(0,o.Lk)("div",Ca,[(0,o.Lk)("div",ba,[t[19]||(t[19]=(0,o.Lk)("span",{class:"star-label"},"5星",-1)),(0,o.bF)(c,{percentage:i.fiveStarPercent,status:"success","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",ya,(0,l.v_)(i.fiveStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",fa,[t[20]||(t[20]=(0,o.Lk)("span",{class:"star-label"},"4星",-1)),(0,o.bF)(c,{percentage:i.fourStarPercent,status:"success","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",La,(0,l.v_)(i.fourStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",wa,[t[21]||(t[21]=(0,o.Lk)("span",{class:"star-label"},"3星",-1)),(0,o.bF)(c,{percentage:i.threeStarPercent,status:"warning","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",_a,(0,l.v_)(i.threeStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",Sa,[t[22]||(t[22]=(0,o.Lk)("span",{class:"star-label"},"2星",-1)),(0,o.bF)(c,{percentage:i.twoStarPercent,status:"warning","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",Ea,(0,l.v_)(i.twoStarPercent.toFixed(0))+"%",1)]),(0,o.Lk)("div",xa,[t[23]||(t[23]=(0,o.Lk)("span",{class:"star-label"},"1星",-1)),(0,o.bF)(c,{percentage:i.oneStarPercent,status:"exception","show-text":!1,"stroke-width":8},null,8,["percentage"]),(0,o.Lk)("span",Pa,(0,l.v_)(i.oneStarPercent.toFixed(0))+"%",1)])])])]),(0,o.Lk)("div",Ma,[t[25]||(t[25]=(0,o.Lk)("div",{class:"section-header"},[(0,o.Lk)("h2",null,[(0,o.Lk)("span",{class:"icon"},"🤖"),(0,o.eW)(" AI 课程总结 "),(0,o.Lk)("span",{class:"beta-badge"},"Beta")]),(0,o.Lk)("span",{class:"ai-disclaimer"},"内容由 DeepSeek V3 生成,仅供参考")],-1)),(0,o.Lk)("div",Ta,[i.displayedSummary?((0,o.uX)(),(0,o.CE)("div",Ia,[(0,o.eW)((0,l.v_)(i.displayedSummary),1),i.isTyping?((0,o.uX)(),(0,o.CE)("span",Xa,"|")):(0,o.Q3)("",!0)])):((0,o.uX)(),(0,o.CE)("p",ja,"当前课程的评分和评论数据过少,暂不能生成AI总结。"))])]),(0,o.Lk)("div",$a,[(0,o.Lk)("div",Fa,[t[27]||(t[27]=(0,o.Lk)("h2",null,"课程评论",-1)),(0,o.Lk)("div",Na,[(0,o.Lk)("span",{class:(0,l.C4)({active:"like_count"===i.sortBy}),onClick:t[2]||(t[2]=e=>r.changeSort("like_count"))},"最热",2),t[26]||(t[26]=(0,o.Lk)("span",{class:"divider"},"|",-1)),(0,o.Lk)("span",{class:(0,l.C4)({active:"comment_time"===i.sortBy}),onClick:t[3]||(t[3]=e=>r.changeSort("comment_time"))},"最新",2)])]),(0,o.Lk)("div",Aa,[(0,o.Lk)("div",za,[(0,o.bo)((0,o.Lk)("input",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.nickname=e),placeholder:"一句话概括您的评论",class:"nickname-input"},null,512),[[a.Jo,i.nickname]]),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[5]||(t[5]=e=>i.commentContent=e),placeholder:"分享您的课程体验、学习难度、考核方式等...",class:"comment-textarea"},null,512),[[a.Jo,i.commentContent]])]),(0,o.Lk)("button",{onClick:t[6]||(t[6]=(...e)=>r.submitComment&&r.submitComment(...e)),class:"submit-btn"},"提交评论")]),r.filteredComments&&r.filteredComments.length>0?((0,o.uX)(),(0,o.CE)("div",Wa,[((0,o.uX)(!0),(0,o.CE)(o.FK,null,(0,o.pI)(i.comments,(e=>((0,o.uX)(),(0,o.CE)("div",{key:e.comment_id,class:"comment-item"},[(0,o.Lk)("div",Ua,[(0,o.Lk)("span",Oa,(0,l.v_)(e.nickname),1),(0,o.Lk)("span",Va,(0,l.v_)(r.formatTime(e.comment_time)),1)]),(0,o.Lk)("div",Ra,(0,l.v_)(e.comment_content),1),(0,o.Lk)("div",Da,[(0,o.Lk)("div",qa,[t[28]||(t[28]=(0,o.eW)(" 评分: ")),(0,o.Lk)("span",null,(0,l.v_)(e.rating),1)]),(0,o.Lk)("div",Ba,[(0,o.Lk)("span",{class:(0,l.C4)(["like-btn",{liked:e.is_liked}]),onClick:t=>r.toggleLike(e)}," ❤ "+(0,l.v_)(e.like_count),11,Qa),e.deleteable?((0,o.uX)(),(0,o.CE)("button",{key:0,onClick:t=>r.deleteComment(e.comment_id),class:"action-link delete"}," 删除 ",8,Ja)):(0,o.Q3)("",!0)])])])))),128))])):((0,o.uX)(),(0,o.CE)("div",Ka,t[29]||(t[29]=[(0,o.Lk)("p",null,"暂无评论,快来抢沙发吧!",-1)])))])])),(0,o.bF)(a.eB,{name:"fade"},{default:(0,o.k6)((()=>[i.showShareModal?((0,o.uX)(),(0,o.CE)("div",Ha," 链接复制成功,快去分享给其他小伙伴吧! ")):(0,o.Q3)("",!0)])),_:1}),(0,o.bF)(a.eB,{name:"fade"},{default:(0,o.k6)((()=>[i.showErrorModal?((0,o.uX)(),(0,o.CE)("div",Ga," 获取数据失败,正在刷新页面... ")):(0,o.Q3)("",!0)])),_:1}),i.isChatModalVisible?((0,o.uX)(),(0,o.CE)("div",Ya,[(0,o.Lk)("div",Za,[(0,o.Lk)("span",{class:"close-btn",onClick:t[7]||(t[7]=(...e)=>r.closeChatModal&&r.closeChatModal(...e))},"×"),t[30]||(t[30]=(0,o.Lk)("h3",null,"发起聊天",-1)),(0,o.bo)((0,o.Lk)("textarea",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.chatMessage=e),placeholder:"请输入聊天内容(至少6个字符)",class:"modal-textarea"},null,512),[[a.Jo,i.chatMessage]]),(0,o.Lk)("div",eo,[(0,o.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>r.submitChat&&r.submitChat(...e)),disabled:i.chatMessage.length<6,class:"primary-btn"},"发起",8,to)])])])):(0,o.Q3)("",!0),i.isConversationExistsModalVisible?((0,o.uX)(),(0,o.CE)("div",so,[(0,o.Lk)("div",ao,[(0,o.Lk)("span",{class:"close-btn",onClick:t[10]||(t[10]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"×"),t[31]||(t[31]=(0,o.Lk)("h3",null,"提示",-1)),t[32]||(t[32]=(0,o.Lk)("p",null,"在此课程下,您与此用户已有会话!",-1)),(0,o.Lk)("div",oo,[(0,o.Lk)("button",{onClick:t[11]||(t[11]=e=>r.navigateToConversation(i.existingConversationId)),class:"primary-btn"},"进入会话"),(0,o.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e)),class:"secondary-btn"},"取消")])])])):(0,o.Q3)("",!0)])}var io={name:"CourseDetail",data(){return{courseId:null,loading:!0,course:{},token:null,userRating:0,totalRating:0,fiveStarPercent:0,fourStarPercent:0,threeStarPercent:0,twoStarPercent:0,oneStarPercent:0,comments:[],nickname:"",commentContent:"",sortBy:"like_count",showShareModal:!1,cachedEmail:null,isChatModalVisible:!1,isConversationExistsModalVisible:!1,chatMessage:"",currentCommentId:null,existingConversationId:null,showErrorModal:!1,aiSummary:null,displayedSummary:"",isTyping:!1,shouldStopTyping:!1}},computed:{filteredComments(){return this.comments.length>0?this.comments:null}},async created(){this.courseId=this.$route.params.course_id,this.courseId?(await this.loadCourseData(),this.course&&this.course.course_name&&(document.title=this.course.course_name+" ("+this.course.teachers+") - NEU小站课程评分系统")):(this.loading=!1,this.$router.replace("/404"))},beforeUnmount(){this.shouldStopTyping=!0},methods:{async loadCourseData(){this.loading=!0,this.course={},this.aiSummary=null,this.displayedSummary="",this.isTyping=!1,this.shouldStopTyping=!1;try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/course-detail?course_id=${this.courseId}`);if(404===e.status)return void this.$router.replace("/404");if(!e.ok)throw new Error("Failed to fetch course detail");this.course=await e.json(),this.getToken(),await Promise.all([this.fetchAndCacheEmail(),this.fetchRatingDistribution(),this.fetchUserRating(),this.fetchComments(),this.fetchAISummary()])}catch(e){console.error("Error loading course data:",e)}finally{this.loading=!1,this.aiSummary&&this.$nextTick((()=>{this.typewriterEffect(this.aiSummary)}))}},getToken(){const e=document.cookie.split("; ").find((e=>e.startsWith("token=")));this.token=e?e.split("=")[1]:null},changeSort(e){this.sortBy!==e&&(this.sortBy=e,this.fetchComments())},getCategoryName(e){const t={1:"选修课-通识选修类",2:"选修课-人文选修类",3:"选修课-专业方向类",4:"选修课-体育类",5:"选修课-学科基础类",6:"选修课-暑期国际课",7:"选修课-数学与自然科学类",8:"选修课-重修专栏",9:"必修课-数学与自然科学类",10:"必修课-人文社会科学类",11:"必修课-学科基础类",12:"必修课-专业方向类",13:"必修课-实践类"};return t[e]||"未知分类"},getCollegeName(e){const t={59:"未填写",1:"材料科学与工程学院",2:"创新创业学院",3:"档案馆",4:"党委宣传部",5:"党委组织部",6:"发展规划与学科建设处",7:"佛山研究生创新学院",8:"工程训练中心",9:"工会",10:"工商管理学院",11:"国防教育学院",12:"国际教育学院",13:"后勤服务中心",14:"后勤管理处",15:"浑南管委会",16:"江河建筑学院",17:"尖子班",18:"教务处",19:"基础学院",20:"计划财经处",21:"机器人科学与工程学院",22:"计算机科学与工程学院",23:"计算中心",24:"纪委",25:"机械工程与自动化学院",26:"继续教育学院",27:"科技产业集团",28:"科学技术研究院",29:"理学院",30:"马克思主义学院",31:"民族教育学院",33:"人事处",34:"人文选修课群",35:"软件学院",36:"生命科学与健康学院",37:"体育部",38:"体育场馆管理中心",39:"团委",40:"图书馆",41:"外国语学院",42:"外联处",43:"网络教育学院",44:"未来技术学院",45:"文法学院",46:"校长办公室",47:"信息科学与工程学院",48:"新知识课群",49:"学生处",50:"学生创新中心",51:"学生指导服务中心",52:"研究生院",53:"冶金学院",54:"艺术学院",55:"医学与生物信息工程学院",56:"医院",57:"资产与实验室管理处",58:"资源与土木工程学院"};return t[e]||"未知院系"},async fetchRatingDistribution(){const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-course-ratings-distribution?course_id=${this.courseId}`);if(e.ok){const t=await e.json();this.totalRating=t.total_rating||0,this.fiveStarPercent=100*t.five_stars,this.fourStarPercent=100*t.four_stars,this.threeStarPercent=100*t.three_stars,this.twoStarPercent=100*t.two_stars,this.oneStarPercent=100*t.one_star}else this.totalRating=0,this.fiveStarPercent=0,this.fourStarPercent=0,this.threeStarPercent=0,this.twoStarPercent=0,this.oneStarPercent=0},async fetchUserRating(){if(!this.token)return;const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-user-rating?course_id=${this.courseId}`,{headers:{Authorization:this.token}});if(200===e.status){const t=await e.json();this.userRating=t.rating}else this.userRating=0},highlightStars(e){this.userRating=e},resetStars(){this.fetchUserRating()},confirmRating(e){confirm(`您确定要给课程 "${this.course.course_name}" 评分:${e}.0 吗?此评分将覆盖之前的评分。`)&&this.submitRating(e)},async submitRating(e){const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-rating",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.courseId,rating:e})});t.ok&&(this.fetchRatingDistribution(),this.fetchUserRating())},async typewriterEffect(e,t=10){this.isTyping=!0,this.displayedSummary="",this.shouldStopTyping=!1;for(let s=0;ssetTimeout(e,t)))}this.isTyping=!1},async fetchAISummary(){try{const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/ai_summary/summary?course_id=${this.courseId}`);if(!e.ok)return void(this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。");const t=await e.json();t.summary?this.aiSummary=t.summary:this.displayedSummary="当前课程的评分和评论数据过少,暂不能生成AI总结。"}catch(e){this.displayedSummary="生成AI总结时出错,请稍后再试。"}},async fetchComments(){try{this.token;const e=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-comments?course_id=${this.courseId}&sort_by=${this.sortBy}`,{headers:{Authorization:this.token}});if(404===e.status)return void(this.comments=[]);if(!e.ok)throw new Error("获取评论失败");const t=await e.json();this.comments=t.comments}catch(e){console.error(e)}},async toggleLike(e){const t=e.is_liked?"unlike-comment":"like-comment";await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/${t}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e.comment_id})}),this.fetchComments()},async submitComment(){this.nickname.length<2||this.commentContent.length<6?alert("一句话概括请至少包含2个字符,评论请至少包含6个字符。"):(await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({course_id:this.courseId,nickname:this.nickname,comment_content:this.commentContent})}),this.fetchComments(),this.nickname="",this.commentContent="")},async deleteComment(e){if(!confirm("确定删除评论吗?"))return;const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/delete-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:e})});t.ok&&this.fetchComments()},formatTime(e){const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},async fetchAndCacheEmail(){if(!this.cachedEmail&&this.token)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token}}),t=await e.json();e.ok&&t.email&&(this.cachedEmail=t.email)}catch(e){console.error(e)}},base64Encode(e){return btoa(e)},shareCourse(){const e=`https://course.xn--xhq44jb2fzpc.com/detail/${this.courseId}`;this.copyToClipboard(e),this.showShareModal=!0,setTimeout((()=>{this.showShareModal=!1}),3e3)},copyToClipboard(e){const t=document.createElement("textarea");t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)},openChatModal(e){this.currentCommentId=e,this.chatMessage="",this.isChatModalVisible=!0},closeChatModal(){this.isChatModalVisible=!1},closeConversationExistsModal(){this.isConversationExistsModalVisible=!1},async submitChat(){if(this.chatMessage.length<6)alert("聊天内容需至少6个字符");else try{const e=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/chat/start-conversation",{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.token},body:JSON.stringify({comment_id:this.currentCommentId,content:this.chatMessage})}),t=await e.json();e.ok&&"Conversation started successfully"===t.message?this.$router.push(`/chat?mid=${t.conversation_id}`):e.ok&&"Conversation already exists"===t.message?(this.existingConversationId=t.conversation_id,this.isConversationExistsModalVisible=!0):alert(t.error||"发起会话失败")}catch(e){alert("发起会话失败,请稍后再试")}finally{this.closeChatModal()}},navigateToConversation(e){this.$router.push(`/chat?mid=${e}`),this.closeConversationExistsModal()}}};const ro=(0,C.A)(io,[["render",no],["__scopeId","data-v-2adb15a0"]]);var co=ro;const lo={class:"not-found-page"},uo={class:"content"};function ho(e,t,s,a,n,i){const r=(0,o.g2)("router-link");return(0,o.uX)(),(0,o.CE)("div",lo,[(0,o.Lk)("div",uo,[t[1]||(t[1]=(0,o.Lk)("div",{class:"error-icon"},"⚠️",-1)),t[2]||(t[2]=(0,o.Lk)("h1",{class:"error-code"},"404",-1)),t[3]||(t[3]=(0,o.Lk)("p",{class:"error-message"},"未知页面",-1)),t[4]||(t[4]=(0,o.Lk)("p",{class:"description"},"抱歉,您访问的页面不存在或已被移除。",-1)),(0,o.bF)(r,{to:"/",class:"home-btn"},{default:(0,o.k6)((()=>t[0]||(t[0]=[(0,o.eW)("返回首页")]))),_:1})])])}var mo={name:"NotFound",created(){document.title="未知页面 - NEU小站课程评分系统"}};const po=(0,C.A)(mo,[["render",ho],["__scopeId","data-v-655c3ea4"]]);var go=po;const ko=[{path:"/",name:"home",meta:{title:"NEU小站课程评分系统"},component:X},{path:"/courses",name:"course-list",meta:{title:"我的课程 - NEU小站课程评分系统"},component:Ce},{path:"/rating",name:"rating",meta:{title:"选修课列表 - NEU小站课程评分系统"},component:tt},{path:"/ratingforcomp",name:"ratingforcomp",meta:{title:"必修课列表 - NEU小站课程评分系统"},component:zt},{path:"/chat",name:"chat",meta:{title:"我的聊天 - NEU小站课程评分系统"},component:Us},{path:"/about",name:"about",meta:{title:"关于 - NEU小站课程评分系统"},component:Qs},{path:"/detail/:course_id",name:"course-detail",meta:{title:"课程详情 - NEU小站课程评分系统"},component:co},{path:"/404",name:"NotFound",meta:{title:"404 - 未知页面 - NEU小站课程评分系统"},component:go},{path:"/:pathMatch(.*)*",redirect:"/404"}],vo=(0,S.aE)({history:(0,S.LA)(),routes:ko});vo.beforeEach(((e,t,s)=>{document.title=e.meta.title||"默认标题",s()}));var Co=vo;const bo=(0,a.Ef)(w);bo.use(Co),bo.use(_.A),bo.mount("#app"),es.A.defaults.baseURL="https://coursesystem.xn--xhq44jb2fzpc.com/",bo.config.globalProperties.$axios=es.A}},t={};function s(a){var o=t[a];if(void 0!==o)return o.exports;var n=t[a]={exports:{}};return e[a].call(n.exports,n,n.exports,s),n.exports}s.m=e,function(){var e=[];s.O=function(t,a,o,n){if(!a){var i=1/0;for(u=0;u=n)&&Object.keys(s.O).every((function(e){return s.O[e](a[c])}))?a.splice(c--,1):(r=!1,n0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[a,o,n]}}(),function(){s.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return s.d(t,{a:t}),t}}(),function(){s.d=function(e,t){for(var a in t)s.o(t,a)&&!s.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})}}(),function(){s.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){s.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}}(),function(){var e={524:0};s.O.j=function(t){return 0===e[t]};var t=function(t,a){var o,n,i=a[0],r=a[1],c=a[2],l=0;if(i.some((function(t){return 0!==e[t]}))){for(o in r)s.o(r,o)&&(s.m[o]=r[o]);if(c)var u=c(s)}for(t&&t(a);l { + this.typewriterEffect(this.aiSummary); + }); + } } }, @@ -448,7 +453,6 @@ export default { const result = await response.json(); if (result.summary) { this.aiSummary = result.summary; - await this.typewriterEffect(this.aiSummary); } else { this.displayedSummary = '当前课程的评分和评论数据过少,暂不能生成AI总结。'; }