diff --git a/.gitignore b/.gitignore index c365df7..28acefe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ node_modules node_modules/ server/ +东北大学.com/ +东北大学.com cookie函数.txt file_index.json push_log.json diff --git a/dist/css/app.19feb207.css b/dist/css/app.19feb207.css new file mode 100644 index 0000000..5bbb0cf --- /dev/null +++ b/dist/css/app.19feb207.css @@ -0,0 +1 @@ +.el-menu-vertical-demo[data-v-fa32c4be]{border-right:none;display:flex;flex-direction:column;height:98%;width:250px}.el-menu-item[data-v-fa32c4be]{border-radius:8px}.el-menu-item[data-v-fa32c4be]:hover{background-color:#1d1e1f}.el-menu-item span[data-v-fa32c4be]{margin-left:10px}.sidebar-footer[data-v-fa32c4be]{margin-top:auto;padding:10px;text-align:center;font-size:14px;color:#888}.sidebar-footer a[data-v-fa32c4be]{color:#e0e4e8;text-decoration:none;bottom:20px;width:100%;text-align:center}.sidebar-footer a[data-v-fa32c4be]:hover{color:#9a9ea2;text-decoration:none}.footer-title[data-v-fa32c4be]{font-size:12px;color:#f6f0f0;text-align:center}.footer-info[data-v-fa32c4be]{margin-top:7px;font-size:12px;color:#beb5b5;text-align:center}.footer-info a[data-v-fa32c4be]{color:#beb5b5;text-decoration:none}.footer-info a[data-v-fa32c4be]:hover{color:#a8a4a6}body,html{height:100%;margin:0;padding:0}#app{display:flex;height:100vh}.sidebar{width:250px;background-color:#333;padding:10px;height:98%}.main-content{flex-grow:1;padding:20px;background-color:#fff;max-width:98%;max-height:98%}.forbidden-container{text-align:center;padding:50px;align-items:center;flex-direction:column;justify-content:center}.forbidden-title{color:#d9534f;font-size:2.5rem;margin-bottom:20px}.forbidden-text{font-size:1.25rem;color:#333;margin-bottom:30px}.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}h2[data-v-b83355ba]{color:#333;margin-bottom:10px;font-size:42px}p[data-v-b83355ba]{line-height:1.6;margin-bottom:15px;color:#666}.guide-link[data-v-b83355ba]{color:#0056b3;text-decoration:underline;cursor:pointer}.guide-link[data-v-b83355ba]:hover{color:#003d82}.modal-overlay[data-v-c515cfa2]{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-c515cfa2]{display:flex;align-items:center;justify-content:center;flex-direction:column;text-align:center;height:200px}.el-icon[data-v-c515cfa2]{font-size:40px;margin-bottom:10px}.modal-content[data-v-c515cfa2]{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-c515cfa2]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.course-detail[data-v-c515cfa2]{max-height:calc(90vh - 120px);overflow-y:auto;overflow-x:auto;padding-right:15px;width:40%}.course-detail[data-v-c515cfa2]::-webkit-scrollbar{width:6px;height:6px}.course-detail[data-v-c515cfa2]::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.course-detail[data-v-c515cfa2]::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.course-detail[data-v-c515cfa2]::-webkit-scrollbar-thumb:hover{background:#555}.course-detail[data-v-c515cfa2]>*{min-width:-moz-fit-content;min-width:fit-content}.rating-section[data-v-c515cfa2]{margin-top:20px}.total-rating[data-v-c515cfa2]{font-size:40px;margin-bottom:10px}.stars span[data-v-c515cfa2]{font-size:30px;cursor:pointer;transition:color .3s}.stars .highlighted[data-v-c515cfa2]{color:gold}.stars span[data-v-c515cfa2]:not(.highlighted){color:#ccc}.comment-section[data-v-c515cfa2]{width:55%;padding-left:20px}.comments-list[data-v-c515cfa2]{max-height:350px;overflow-y:auto;margin-bottom:20px}.comment[data-v-c515cfa2]{padding:10px 0;border-bottom:1px solid #ddd}.like-section[data-v-c515cfa2]{cursor:pointer;color:gray}.like-section.liked[data-v-c515cfa2]{color:red}.new-comment[data-v-c515cfa2]{display:flex;flex-direction:column}.new-comment input[data-v-c515cfa2],.new-comment textarea[data-v-c515cfa2]{margin-bottom:10px;padding:5px;border-radius:5px;border:1px solid #ccc}.new-comment button[data-v-c515cfa2]{padding:10px;background-color:#007bff;color:#fff;border:none;border-radius:5px;cursor:pointer}.comment-meta[data-v-c515cfa2],.comment-time[data-v-c515cfa2]{font-size:13px}.progress[data-v-c515cfa2]{margin-bottom:5px;width:250px}[data-v-c515cfa2] .progress .el-progress-bar__outer{height:20px!important;line-height:40px;background-color:#a19999}.course-title[data-v-c515cfa2]{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-c515cfa2]{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-c515cfa2]:hover{background-color:#45a049}.error-modal[data-v-c515cfa2],.share-modal[data-v-c515cfa2]{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-c515cfa2 .5s ease}.share-modal[data-v-c515cfa2]{background-color:#4caf50}.error-modal[data-v-c515cfa2]{background-color:#f44}@keyframes fadeInDown-c515cfa2{0%{opacity:0;transform:translate(-50%,-30px)}to{opacity:1;transform:translate(-50%)}}.chat-start-btn[data-v-c515cfa2]{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-c515cfa2]:hover{background-color:#66b1ff;transform:scale(1.05)}.chat-start-btn[data-v-c515cfa2]:active{background-color:#3a8ee6;transform:scale(.95)}.chat-modal-overlay[data-v-c515cfa2]{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;justify-content:center;align-items:center;z-index:1000;animation:chat-fadeIn-c515cfa2 .3s ease}.chat-modal-content[data-v-c515cfa2]{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-c515cfa2 .3s ease;position:relative}.chat-modal-content .chat-close-btn[data-v-c515cfa2]{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-c515cfa2]:hover{color:#333}.chat-modal-content h3[data-v-c515cfa2]{margin-top:0;color:#333;font-size:18px}.chat-modal-actions[data-v-c515cfa2]{margin-top:20px;display:flex;justify-content:space-around}.chat-modal-actions button[data-v-c515cfa2]{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-c515cfa2]:first-child{background-color:#409eff;color:#fff}.chat-modal-actions button[data-v-c515cfa2]:first-child:hover{background-color:#66b1ff}.chat-modal-actions button[data-v-c515cfa2]:first-child:active{background-color:#3a8ee6}.chat-modal-actions button[data-v-c515cfa2]:last-child{background-color:#f5f5f5;color:#666}.chat-modal-actions button[data-v-c515cfa2]:last-child:hover{background-color:#e0e0e0}.chat-modal-actions button[data-v-c515cfa2]:last-child:active{background-color:#d6d6d6}.chat-textarea[data-v-c515cfa2]{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-c515cfa2]:focus{border-color:#409eff}@keyframes chat-fadeIn-c515cfa2{0%{opacity:0}to{opacity:1}}@keyframes chat-slideIn-c515cfa2{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}.delete-btn[data-v-c515cfa2]{color:red;background:none;border:none;cursor:pointer;margin-left:10px;font-size:14px;padding:2px 8px}.delete-btn[data-v-c515cfa2]:hover{text-decoration:underline}.comment-actions[data-v-c515cfa2]{display:flex;align-items:center;margin-top:10px;font-size:14px}.ai-summary[data-v-c515cfa2]{margin-top:15px;padding:10px;background-color:#f5f5f5;border-radius:4px;line-height:1.5}.typing-cursor[data-v-c515cfa2]{display:inline-block;animation:blink-c515cfa2 .7s infinite;font-weight:700}@keyframes blink-c515cfa2{0%,to{opacity:1}50%{opacity:0}}.loading-message[data-v-0b028aca]{font-size:16px;color:#666;text-align:center;margin-top:20px}.course-table[data-v-0b028aca]{width:100%;border-collapse:collapse;max-height:270px;overflow-y:auto}.course-table thead[data-v-0b028aca]{position:sticky;top:0;z-index:1}.course-table td[data-v-0b028aca],.course-table th[data-v-0b028aca]{padding:10px;border-bottom:1px solid #ddd;text-align:left}.course-table th[data-v-0b028aca]{background-color:#f1f1f1;font-weight:700;box-shadow:0 2px 2px -1px rgba(0,0,0,.1)}.course-table tr[data-v-0b028aca]:hover{background-color:#f9f9f9}.input-section input[data-v-0b028aca],.input-section select[data-v-0b028aca]{display:block;margin:10px 0;padding:10px;width:100%;max-width:400px;border:1px solid #ccc;border-radius:4px;font-size:16px;transition:all .3s ease}.input-section input[data-v-0b028aca]:focus,.input-section select[data-v-0b028aca]:focus{border-color:#007bff;outline:none;box-shadow:0 0 8px rgba(0,123,255,.5)}.input-section button[data-v-0b028aca]{padding:10px 20px;background-color:#007bff;color:#fff;border:none;border-radius:8px;cursor:pointer;transition:transform .2s ease,background-color .3s ease}.input-section button[data-v-0b028aca]:hover{background-color:#0056b3;transform:scale(1.05)}.input-section button[data-v-0b028aca]:active{transform:scale(.95)}.pagination-bar[data-v-0b028aca]{margin-top:20px;text-align:center}.pagination-bar button[data-v-0b028aca]{margin:0 5px;padding:5px 10px;cursor:pointer;border:1px solid #ddd;border-radius:4px;background-color:#fff;transition:all .3s ease}.pagination-bar button[data-v-0b028aca]:hover{background-color:#0400f9;border-color:#0400f9;color:#fff}.pagination-bar .active[data-v-0b028aca]{background-color:#007bff;color:#fff;border-color:#007bff}.clickable-text[data-v-0b028aca]{color:#007bff;cursor:pointer;text-decoration:none;transition:color .2s ease}.clickable-text[data-v-0b028aca]:hover{color:#00008b}.clickable-text[data-v-0b028aca]:active{color:navy}.empty-message[data-v-0b028aca]{text-align:center;padding:20px;color:#666;font-size:16px}.section-header[data-v-0b028aca]{display:flex;align-items:center;gap:15px;margin-bottom:0}.help-btn[data-v-0b028aca]{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-0b028aca]:hover{background:#e9ecef}.help-icon[data-v-0b028aca]{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}.help-modal[data-v-0b028aca]{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-0b028aca]{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-0b028aca]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #dee2e6}.close-btn[data-v-0b028aca]{background:none;border:none;font-size:24px;cursor:pointer;color:#6c757d}.help-section[data-v-0b028aca]{margin-bottom:20px}.help-modal-header h3[data-v-0b028aca]{font-size:24px;font-weight:700;margin-bottom:4px}.help-section h4[data-v-0b028aca]{color:#0056b3;margin-bottom:10px}.help-section p[data-v-0b028aca]{color:#495057;line-height:1.6;margin-bottom:8px}.rating-page[data-v-392e0a1a]{padding:20px}.search-sort-bar[data-v-392e0a1a]{display:flex;flex-wrap:wrap;gap:15px;margin-bottom:20px;align-items:center}.search-sort-bar input[type=text][data-v-392e0a1a]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;width:200px}.search-sort-bar button[data-v-392e0a1a]{padding:8px 16px;background-color:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;transition:transform .2s ease}.search-sort-bar button[data-v-392e0a1a]:hover{background-color:#0056b3}.search-sort-bar button[data-v-392e0a1a]:active{transform:scale(.9)}.category-checkboxes label[data-v-392e0a1a]{display:flex;align-items:center;font-size:14px;cursor:pointer}.category-checkboxes input[type=checkbox][data-v-392e0a1a]{margin-right:6px;transform:scale(1.2);cursor:pointer}.search-sort-bar select[data-v-392e0a1a]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;cursor:pointer}.search-sort-bar select[data-v-392e0a1a]:focus{border-color:#007bff;outline:none}.category-checkboxes[data-v-392e0a1a]{display:flex;gap:10px}.course-cards[data-v-392e0a1a]{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;max-height:55vh;overflow-y:auto;overflow-x:hidden}.course-card[data-v-392e0a1a]{border:1px solid #ddd;padding:20px;border-radius:8px;cursor:pointer;transition:transform .3s;box-shadow:0 4px 8px rgba(29,28,28,.2);max-width:33vw}.course-card[data-v-392e0a1a]:hover{transform:scale(1.05)}.course-title[data-v-392e0a1a]{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}.pagination-bar[data-v-392e0a1a]{margin-top:20px;text-align:center}.pagination-bar button[data-v-392e0a1a]{margin:0 5px;padding:5px 10px;cursor:pointer;border:1px solid #ddd;border-radius:4px;background-color:#fff;transition:all .3s ease}.pagination-bar button[data-v-392e0a1a]:hover{background-color:#0400f9;border-color:#0400f9;color:#fff}.pagination-bar .active[data-v-392e0a1a]{background-color:#007bff;color:#fff;border-color:#007bff}.course-detail-modal[data-v-392e0a1a]{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}.modal-content[data-v-392e0a1a]{background-color:#fff;padding:20px;border-radius:8px;width:400px;position:relative}.modal-content .close[data-v-392e0a1a]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.card-rate[data-v-392e0a1a]{font-size:22px;text-align:right;color:red}.unit[data-v-392e0a1a]{font-size:14px}.card-topcomment[data-v-392e0a1a]{font-size:15px}.card-college[data-v-392e0a1a],.card-ratecount[data-v-392e0a1a],.card-teachers[data-v-392e0a1a],.card-type[data-v-392e0a1a]{font-size:14px}.rating-note[data-v-392e0a1a]{font-size:18px}.select-container select[data-v-22fe0ea1]{display:inline-block}.sortBySelect[data-v-22fe0ea1]{margin-right:15px}.rating-page[data-v-22fe0ea1]{padding:20px}.search-sort-bar[data-v-22fe0ea1]{display:flex;flex-wrap:wrap;gap:15px;margin-bottom:20px;align-items:center}.search-sort-bar input[type=text][data-v-22fe0ea1]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;width:200px}.search-sort-bar button[data-v-22fe0ea1]{padding:8px 16px;background-color:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;transition:transform .2s ease}.search-sort-bar button[data-v-22fe0ea1]:hover{background-color:#0056b3}.search-sort-bar button[data-v-22fe0ea1]:active{transform:scale(.9)}.category-checkboxes label[data-v-22fe0ea1]{display:flex;align-items:center;font-size:14px;cursor:pointer}.category-checkboxes input[type=checkbox][data-v-22fe0ea1]{margin-right:6px;transform:scale(1.2);cursor:pointer}.search-sort-bar select[data-v-22fe0ea1]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;cursor:pointer}.search-sort-bar select[data-v-22fe0ea1]:focus{border-color:#007bff;outline:none}.category-checkboxes[data-v-22fe0ea1]{display:flex;gap:10px}.course-cards[data-v-22fe0ea1]{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;max-height:55vh;overflow-y:auto;overflow-x:hidden}.course-card[data-v-22fe0ea1]{border:1px solid #ddd;padding:20px;border-radius:8px;cursor:pointer;transition:transform .3s;box-shadow:0 4px 8px rgba(29,28,28,.2);max-width:33vw}.course-card[data-v-22fe0ea1]:hover{transform:scale(1.05)}.course-title[data-v-22fe0ea1]{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}.pagination-bar[data-v-22fe0ea1]{margin-top:20px;text-align:center}.pagination-bar button[data-v-22fe0ea1]{margin:0 5px;padding:5px 10px;cursor:pointer;border:1px solid #ddd;border-radius:4px;background-color:#fff;transition:all .3s ease}.pagination-bar button[data-v-22fe0ea1]:hover{background-color:#0400f9;border-color:#0400f9;color:#fff}.pagination-bar .active[data-v-22fe0ea1]{background-color:#007bff;color:#fff;border-color:#007bff}.course-detail-modal[data-v-22fe0ea1]{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}.modal-content[data-v-22fe0ea1]{background-color:#fff;padding:20px;border-radius:8px;width:400px;position:relative}.modal-content .close[data-v-22fe0ea1]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.card-rate[data-v-22fe0ea1]{font-size:22px;text-align:right;color:red}.unit[data-v-22fe0ea1]{font-size:14px}.card-topcomment[data-v-22fe0ea1]{font-size:15px}.card-college[data-v-22fe0ea1],.card-ratecount[data-v-22fe0ea1],.card-teachers[data-v-22fe0ea1],.card-type[data-v-22fe0ea1]{font-size:14px}.rating-note[data-v-22fe0ea1]{font-size:18px}.chat-page[data-v-0f09629d]{display:flex;height:100vh;overflow:hidden}.sidebar[data-v-0f09629d]{width:300px;border-right:1px solid #ddd;display:flex;flex-direction:column;padding:10px;background-color:#f9f9f9}.sidebar h3[data-v-0f09629d]{margin-bottom:10px}.conversation-item[data-v-0f09629d]{padding:10px;margin:5px 0;border-radius:5px;cursor:pointer;background-color:#fff;transition:background-color .2s}.conversation-item[data-v-0f09629d]:hover{background-color:#f0f0f0}.conversation-item.active[data-v-0f09629d]{background-color:#e6f7ff;border-left:4px solid #1890ff}.conversation-name[data-v-0f09629d]{font-weight:700;display:flex;align-items:center}.role-label[data-v-0f09629d]{color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.role-label.owner[data-v-0f09629d]{background-color:#2196f3}.role-label.member[data-v-0f09629d]{background-color:#4caf50}.conversation-last-message[data-v-0f09629d],.conversation-updated-at[data-v-0f09629d]{color:#999;font-size:12px}.new-message-label[data-v-0f09629d]{background-color:red;color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.chat-container[data-v-0f09629d]{flex:1;display:flex;flex-direction:column;background-color:#f5f5f5;width:60vw;height:100vh;position:relative}.conversation-info[data-v-0f09629d]{padding:10px;background-color:#fff;border-bottom:1px solid #ddd;display:flex;justify-content:space-between;align-items:center}.message-list[data-v-0f09629d]{flex:1;padding:10px;overflow-y:auto}.message[data-v-0f09629d]{margin:10px 0;display:flex;flex-direction:column}.message.self[data-v-0f09629d]{align-items:flex-end}.message.other[data-v-0f09629d]{align-items:flex-start}.message-bubble[data-v-0f09629d]{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-0f09629d]{background-color:#daf1da}.message-info[data-v-0f09629d]{display:flex;margin-top:5px}.message-info.align-right[data-v-0f09629d]{justify-content:flex-end}.message-info.align-left[data-v-0f09629d]{justify-content:flex-start}.message-info small[data-v-0f09629d]{color:#999;font-size:12px;margin-left:5px}.input-container[data-v-0f09629d]{padding:10px;border-top:1px solid #ddd;text-align:center}.locked-input[data-v-0f09629d]{height:60px}.locked-input[data-v-0f09629d] .el-textarea__inner{resize:none!important}.header[data-v-0f09629d]{display:flex;justify-content:space-between;align-items:center}.connection-status[data-v-0f09629d]{display:flex;align-items:center;font-size:14px}.status-indicator[data-v-0f09629d]{width:8px;height:8px;border-radius:50%;margin-right:5px}.status-indicator.connected[data-v-0f09629d]{background-color:#02f23e}.status-indicator.disconnected[data-v-0f09629d]{background-color:#f44336}.status-text[data-v-0f09629d]{font-size:14px;font-weight:400}.connected .status-text[data-v-0f09629d]{color:#02f23e}.disconnected .status-text[data-v-0f09629d]{color:#f44336}.about-container[data-v-0adf4200]{height:90vh;overflow:hidden;padding:20px}.about-page[data-v-0adf4200]{max-width:99%;margin:0 auto;height:100%;overflow-y:auto;padding-right:15px}.about-page[data-v-0adf4200]::-webkit-scrollbar{width:6px}.about-page[data-v-0adf4200]::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.about-page[data-v-0adf4200]::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.about-page[data-v-0adf4200]::-webkit-scrollbar-thumb:hover{background:#555}.project-intro[data-v-0adf4200]{margin-bottom:40px}h2[data-v-0adf4200]{color:#333;margin-bottom:20px;font-size:24px;border-bottom:2px solid #eee;padding-bottom:10px}.intro-content[data-v-0adf4200]{line-height:1.8;color:#666}.intro-content p[data-v-0adf4200]{margin-bottom:15px}.version-timeline[data-v-0adf4200]{margin-top:40px}.version-item[data-v-0adf4200]{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-0adf4200]{color:#409eff;margin:0 0 10px 0}.version-item p[data-v-0adf4200]{color:#666;margin:0}.version-item ul[data-v-0adf4200]{list-style-type:disc;margin:0;padding-left:20px}.version-item li[data-v-0adf4200]{margin-bottom:5px}[data-v-0adf4200] .el-timeline-item__node{background-color:#409eff}[data-v-0adf4200] .el-timeline-item__timestamp{color:#409eff;font-weight:700}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/css/app.63f333fa.css b/dist/css/app.63f333fa.css deleted file mode 100644 index c614bbe..0000000 --- a/dist/css/app.63f333fa.css +++ /dev/null @@ -1 +0,0 @@ -.el-menu-vertical-demo[data-v-474ac5cc]{border-right:none;display:flex;flex-direction:column;height:95vh}.el-menu-item[data-v-474ac5cc]{border-radius:8px}.el-menu-item[data-v-474ac5cc]:hover{background-color:#1d1e1f}.el-menu-item span[data-v-474ac5cc]{margin-left:10px}.sidebar-footer[data-v-474ac5cc]{margin-top:auto;padding:10px;text-align:center;font-size:14px;color:#888}.sidebar-footer a[data-v-474ac5cc]{color:#e0e4e8;text-decoration:none;bottom:20px;width:100%;text-align:center}.sidebar-footer a[data-v-474ac5cc]:hover{color:#9a9ea2;text-decoration:none}.footer-info[data-v-474ac5cc]{margin-top:5px;font-size:10px;color:#beb5b5;text-align:center}body,html{height:100%;margin:0;padding:0}#app{display:flex;height:100vh}.sidebar{width:250px;background-color:#333;padding:10px;height:100vh}.main-content{flex-grow:1;padding:20px;background-color:#fff;max-width:920px}.forbidden-container{text-align:center;padding:50px;align-items:center;flex-direction:column;justify-content:center}.forbidden-title{color:#d9534f;font-size:2.5rem;margin-bottom:20px}.forbidden-text{font-size:1.25rem;color:#333;margin-bottom:30px}.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}h2[data-v-1720d549]{color:#333;margin-bottom:10px;font-size:42px}p[data-v-1720d549]{line-height:1.6;margin-bottom:15px;color:#666}.guide-link[data-v-1720d549]{color:#0056b3;text-decoration:underline;cursor:pointer}.guide-link[data-v-1720d549]:hover{color:#003d82}.modal-overlay[data-v-c515cfa2]{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-c515cfa2]{display:flex;align-items:center;justify-content:center;flex-direction:column;text-align:center;height:200px}.el-icon[data-v-c515cfa2]{font-size:40px;margin-bottom:10px}.modal-content[data-v-c515cfa2]{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-c515cfa2]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.course-detail[data-v-c515cfa2]{max-height:calc(90vh - 120px);overflow-y:auto;overflow-x:auto;padding-right:15px;width:40%}.course-detail[data-v-c515cfa2]::-webkit-scrollbar{width:6px;height:6px}.course-detail[data-v-c515cfa2]::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.course-detail[data-v-c515cfa2]::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.course-detail[data-v-c515cfa2]::-webkit-scrollbar-thumb:hover{background:#555}.course-detail[data-v-c515cfa2]>*{min-width:-moz-fit-content;min-width:fit-content}.rating-section[data-v-c515cfa2]{margin-top:20px}.total-rating[data-v-c515cfa2]{font-size:40px;margin-bottom:10px}.stars span[data-v-c515cfa2]{font-size:30px;cursor:pointer;transition:color .3s}.stars .highlighted[data-v-c515cfa2]{color:gold}.stars span[data-v-c515cfa2]:not(.highlighted){color:#ccc}.comment-section[data-v-c515cfa2]{width:55%;padding-left:20px}.comments-list[data-v-c515cfa2]{max-height:350px;overflow-y:auto;margin-bottom:20px}.comment[data-v-c515cfa2]{padding:10px 0;border-bottom:1px solid #ddd}.like-section[data-v-c515cfa2]{cursor:pointer;color:gray}.like-section.liked[data-v-c515cfa2]{color:red}.new-comment[data-v-c515cfa2]{display:flex;flex-direction:column}.new-comment input[data-v-c515cfa2],.new-comment textarea[data-v-c515cfa2]{margin-bottom:10px;padding:5px;border-radius:5px;border:1px solid #ccc}.new-comment button[data-v-c515cfa2]{padding:10px;background-color:#007bff;color:#fff;border:none;border-radius:5px;cursor:pointer}.comment-meta[data-v-c515cfa2],.comment-time[data-v-c515cfa2]{font-size:13px}.progress[data-v-c515cfa2]{margin-bottom:5px;width:250px}[data-v-c515cfa2] .progress .el-progress-bar__outer{height:20px!important;line-height:40px;background-color:#a19999}.course-title[data-v-c515cfa2]{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-c515cfa2]{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-c515cfa2]:hover{background-color:#45a049}.error-modal[data-v-c515cfa2],.share-modal[data-v-c515cfa2]{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-c515cfa2 .5s ease}.share-modal[data-v-c515cfa2]{background-color:#4caf50}.error-modal[data-v-c515cfa2]{background-color:#f44}@keyframes fadeInDown-c515cfa2{0%{opacity:0;transform:translate(-50%,-30px)}to{opacity:1;transform:translate(-50%)}}.chat-start-btn[data-v-c515cfa2]{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-c515cfa2]:hover{background-color:#66b1ff;transform:scale(1.05)}.chat-start-btn[data-v-c515cfa2]:active{background-color:#3a8ee6;transform:scale(.95)}.chat-modal-overlay[data-v-c515cfa2]{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;justify-content:center;align-items:center;z-index:1000;animation:chat-fadeIn-c515cfa2 .3s ease}.chat-modal-content[data-v-c515cfa2]{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-c515cfa2 .3s ease;position:relative}.chat-modal-content .chat-close-btn[data-v-c515cfa2]{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-c515cfa2]:hover{color:#333}.chat-modal-content h3[data-v-c515cfa2]{margin-top:0;color:#333;font-size:18px}.chat-modal-actions[data-v-c515cfa2]{margin-top:20px;display:flex;justify-content:space-around}.chat-modal-actions button[data-v-c515cfa2]{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-c515cfa2]:first-child{background-color:#409eff;color:#fff}.chat-modal-actions button[data-v-c515cfa2]:first-child:hover{background-color:#66b1ff}.chat-modal-actions button[data-v-c515cfa2]:first-child:active{background-color:#3a8ee6}.chat-modal-actions button[data-v-c515cfa2]:last-child{background-color:#f5f5f5;color:#666}.chat-modal-actions button[data-v-c515cfa2]:last-child:hover{background-color:#e0e0e0}.chat-modal-actions button[data-v-c515cfa2]:last-child:active{background-color:#d6d6d6}.chat-textarea[data-v-c515cfa2]{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-c515cfa2]:focus{border-color:#409eff}@keyframes chat-fadeIn-c515cfa2{0%{opacity:0}to{opacity:1}}@keyframes chat-slideIn-c515cfa2{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}.delete-btn[data-v-c515cfa2]{color:red;background:none;border:none;cursor:pointer;margin-left:10px;font-size:14px;padding:2px 8px}.delete-btn[data-v-c515cfa2]:hover{text-decoration:underline}.comment-actions[data-v-c515cfa2]{display:flex;align-items:center;margin-top:10px;font-size:14px}.ai-summary[data-v-c515cfa2]{margin-top:15px;padding:10px;background-color:#f5f5f5;border-radius:4px;line-height:1.5}.typing-cursor[data-v-c515cfa2]{display:inline-block;animation:blink-c515cfa2 .7s infinite;font-weight:700}@keyframes blink-c515cfa2{0%,to{opacity:1}50%{opacity:0}}.loading-message[data-v-0b028aca]{font-size:16px;color:#666;text-align:center;margin-top:20px}.course-table[data-v-0b028aca]{width:100%;border-collapse:collapse;max-height:270px;overflow-y:auto}.course-table thead[data-v-0b028aca]{position:sticky;top:0;z-index:1}.course-table td[data-v-0b028aca],.course-table th[data-v-0b028aca]{padding:10px;border-bottom:1px solid #ddd;text-align:left}.course-table th[data-v-0b028aca]{background-color:#f1f1f1;font-weight:700;box-shadow:0 2px 2px -1px rgba(0,0,0,.1)}.course-table tr[data-v-0b028aca]:hover{background-color:#f9f9f9}.input-section input[data-v-0b028aca],.input-section select[data-v-0b028aca]{display:block;margin:10px 0;padding:10px;width:100%;max-width:400px;border:1px solid #ccc;border-radius:4px;font-size:16px;transition:all .3s ease}.input-section input[data-v-0b028aca]:focus,.input-section select[data-v-0b028aca]:focus{border-color:#007bff;outline:none;box-shadow:0 0 8px rgba(0,123,255,.5)}.input-section button[data-v-0b028aca]{padding:10px 20px;background-color:#007bff;color:#fff;border:none;border-radius:8px;cursor:pointer;transition:transform .2s ease,background-color .3s ease}.input-section button[data-v-0b028aca]:hover{background-color:#0056b3;transform:scale(1.05)}.input-section button[data-v-0b028aca]:active{transform:scale(.95)}.pagination-bar[data-v-0b028aca]{margin-top:20px;text-align:center}.pagination-bar button[data-v-0b028aca]{margin:0 5px;padding:5px 10px;cursor:pointer;border:1px solid #ddd;border-radius:4px;background-color:#fff;transition:all .3s ease}.pagination-bar button[data-v-0b028aca]:hover{background-color:#0400f9;border-color:#0400f9;color:#fff}.pagination-bar .active[data-v-0b028aca]{background-color:#007bff;color:#fff;border-color:#007bff}.clickable-text[data-v-0b028aca]{color:#007bff;cursor:pointer;text-decoration:none;transition:color .2s ease}.clickable-text[data-v-0b028aca]:hover{color:#00008b}.clickable-text[data-v-0b028aca]:active{color:navy}.empty-message[data-v-0b028aca]{text-align:center;padding:20px;color:#666;font-size:16px}.section-header[data-v-0b028aca]{display:flex;align-items:center;gap:15px;margin-bottom:0}.help-btn[data-v-0b028aca]{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-0b028aca]:hover{background:#e9ecef}.help-icon[data-v-0b028aca]{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}.help-modal[data-v-0b028aca]{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-0b028aca]{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-0b028aca]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #dee2e6}.close-btn[data-v-0b028aca]{background:none;border:none;font-size:24px;cursor:pointer;color:#6c757d}.help-section[data-v-0b028aca]{margin-bottom:20px}.help-modal-header h3[data-v-0b028aca]{font-size:24px;font-weight:700;margin-bottom:4px}.help-section h4[data-v-0b028aca]{color:#0056b3;margin-bottom:10px}.help-section p[data-v-0b028aca]{color:#495057;line-height:1.6;margin-bottom:8px}.rating-page[data-v-392e0a1a]{padding:20px}.search-sort-bar[data-v-392e0a1a]{display:flex;flex-wrap:wrap;gap:15px;margin-bottom:20px;align-items:center}.search-sort-bar input[type=text][data-v-392e0a1a]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;width:200px}.search-sort-bar button[data-v-392e0a1a]{padding:8px 16px;background-color:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;transition:transform .2s ease}.search-sort-bar button[data-v-392e0a1a]:hover{background-color:#0056b3}.search-sort-bar button[data-v-392e0a1a]:active{transform:scale(.9)}.category-checkboxes label[data-v-392e0a1a]{display:flex;align-items:center;font-size:14px;cursor:pointer}.category-checkboxes input[type=checkbox][data-v-392e0a1a]{margin-right:6px;transform:scale(1.2);cursor:pointer}.search-sort-bar select[data-v-392e0a1a]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;cursor:pointer}.search-sort-bar select[data-v-392e0a1a]:focus{border-color:#007bff;outline:none}.category-checkboxes[data-v-392e0a1a]{display:flex;gap:10px}.course-cards[data-v-392e0a1a]{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;max-height:55vh;overflow-y:auto;overflow-x:hidden}.course-card[data-v-392e0a1a]{border:1px solid #ddd;padding:20px;border-radius:8px;cursor:pointer;transition:transform .3s;box-shadow:0 4px 8px rgba(29,28,28,.2);max-width:33vw}.course-card[data-v-392e0a1a]:hover{transform:scale(1.05)}.course-title[data-v-392e0a1a]{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}.pagination-bar[data-v-392e0a1a]{margin-top:20px;text-align:center}.pagination-bar button[data-v-392e0a1a]{margin:0 5px;padding:5px 10px;cursor:pointer;border:1px solid #ddd;border-radius:4px;background-color:#fff;transition:all .3s ease}.pagination-bar button[data-v-392e0a1a]:hover{background-color:#0400f9;border-color:#0400f9;color:#fff}.pagination-bar .active[data-v-392e0a1a]{background-color:#007bff;color:#fff;border-color:#007bff}.course-detail-modal[data-v-392e0a1a]{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}.modal-content[data-v-392e0a1a]{background-color:#fff;padding:20px;border-radius:8px;width:400px;position:relative}.modal-content .close[data-v-392e0a1a]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.card-rate[data-v-392e0a1a]{font-size:22px;text-align:right;color:red}.unit[data-v-392e0a1a]{font-size:14px}.card-topcomment[data-v-392e0a1a]{font-size:15px}.card-college[data-v-392e0a1a],.card-ratecount[data-v-392e0a1a],.card-teachers[data-v-392e0a1a],.card-type[data-v-392e0a1a]{font-size:14px}.rating-note[data-v-392e0a1a]{font-size:18px}.select-container select[data-v-22fe0ea1]{display:inline-block}.sortBySelect[data-v-22fe0ea1]{margin-right:15px}.rating-page[data-v-22fe0ea1]{padding:20px}.search-sort-bar[data-v-22fe0ea1]{display:flex;flex-wrap:wrap;gap:15px;margin-bottom:20px;align-items:center}.search-sort-bar input[type=text][data-v-22fe0ea1]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;width:200px}.search-sort-bar button[data-v-22fe0ea1]{padding:8px 16px;background-color:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;transition:transform .2s ease}.search-sort-bar button[data-v-22fe0ea1]:hover{background-color:#0056b3}.search-sort-bar button[data-v-22fe0ea1]:active{transform:scale(.9)}.category-checkboxes label[data-v-22fe0ea1]{display:flex;align-items:center;font-size:14px;cursor:pointer}.category-checkboxes input[type=checkbox][data-v-22fe0ea1]{margin-right:6px;transform:scale(1.2);cursor:pointer}.search-sort-bar select[data-v-22fe0ea1]{padding:8px 12px;font-size:16px;border:1px solid #ccc;border-radius:4px;cursor:pointer}.search-sort-bar select[data-v-22fe0ea1]:focus{border-color:#007bff;outline:none}.category-checkboxes[data-v-22fe0ea1]{display:flex;gap:10px}.course-cards[data-v-22fe0ea1]{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;max-height:55vh;overflow-y:auto;overflow-x:hidden}.course-card[data-v-22fe0ea1]{border:1px solid #ddd;padding:20px;border-radius:8px;cursor:pointer;transition:transform .3s;box-shadow:0 4px 8px rgba(29,28,28,.2);max-width:33vw}.course-card[data-v-22fe0ea1]:hover{transform:scale(1.05)}.course-title[data-v-22fe0ea1]{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}.pagination-bar[data-v-22fe0ea1]{margin-top:20px;text-align:center}.pagination-bar button[data-v-22fe0ea1]{margin:0 5px;padding:5px 10px;cursor:pointer;border:1px solid #ddd;border-radius:4px;background-color:#fff;transition:all .3s ease}.pagination-bar button[data-v-22fe0ea1]:hover{background-color:#0400f9;border-color:#0400f9;color:#fff}.pagination-bar .active[data-v-22fe0ea1]{background-color:#007bff;color:#fff;border-color:#007bff}.course-detail-modal[data-v-22fe0ea1]{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}.modal-content[data-v-22fe0ea1]{background-color:#fff;padding:20px;border-radius:8px;width:400px;position:relative}.modal-content .close[data-v-22fe0ea1]{position:absolute;top:10px;right:10px;cursor:pointer;font-size:24px}.card-rate[data-v-22fe0ea1]{font-size:22px;text-align:right;color:red}.unit[data-v-22fe0ea1]{font-size:14px}.card-topcomment[data-v-22fe0ea1]{font-size:15px}.card-college[data-v-22fe0ea1],.card-ratecount[data-v-22fe0ea1],.card-teachers[data-v-22fe0ea1],.card-type[data-v-22fe0ea1]{font-size:14px}.rating-note[data-v-22fe0ea1]{font-size:18px}.chat-page[data-v-0f09629d]{display:flex;height:100vh;overflow:hidden}.sidebar[data-v-0f09629d]{width:300px;border-right:1px solid #ddd;display:flex;flex-direction:column;padding:10px;background-color:#f9f9f9}.sidebar h3[data-v-0f09629d]{margin-bottom:10px}.conversation-item[data-v-0f09629d]{padding:10px;margin:5px 0;border-radius:5px;cursor:pointer;background-color:#fff;transition:background-color .2s}.conversation-item[data-v-0f09629d]:hover{background-color:#f0f0f0}.conversation-item.active[data-v-0f09629d]{background-color:#e6f7ff;border-left:4px solid #1890ff}.conversation-name[data-v-0f09629d]{font-weight:700;display:flex;align-items:center}.role-label[data-v-0f09629d]{color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.role-label.owner[data-v-0f09629d]{background-color:#2196f3}.role-label.member[data-v-0f09629d]{background-color:#4caf50}.conversation-last-message[data-v-0f09629d],.conversation-updated-at[data-v-0f09629d]{color:#999;font-size:12px}.new-message-label[data-v-0f09629d]{background-color:red;color:#fff;padding:2px 5px;border-radius:3px;margin-left:5px;font-size:12px}.chat-container[data-v-0f09629d]{flex:1;display:flex;flex-direction:column;background-color:#f5f5f5;width:60vw;height:100vh;position:relative}.conversation-info[data-v-0f09629d]{padding:10px;background-color:#fff;border-bottom:1px solid #ddd;display:flex;justify-content:space-between;align-items:center}.message-list[data-v-0f09629d]{flex:1;padding:10px;overflow-y:auto}.message[data-v-0f09629d]{margin:10px 0;display:flex;flex-direction:column}.message.self[data-v-0f09629d]{align-items:flex-end}.message.other[data-v-0f09629d]{align-items:flex-start}.message-bubble[data-v-0f09629d]{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-0f09629d]{background-color:#daf1da}.message-info[data-v-0f09629d]{display:flex;margin-top:5px}.message-info.align-right[data-v-0f09629d]{justify-content:flex-end}.message-info.align-left[data-v-0f09629d]{justify-content:flex-start}.message-info small[data-v-0f09629d]{color:#999;font-size:12px;margin-left:5px}.input-container[data-v-0f09629d]{padding:10px;border-top:1px solid #ddd;text-align:center}.locked-input[data-v-0f09629d]{height:60px}.locked-input[data-v-0f09629d] .el-textarea__inner{resize:none!important}.header[data-v-0f09629d]{display:flex;justify-content:space-between;align-items:center}.connection-status[data-v-0f09629d]{display:flex;align-items:center;font-size:14px}.status-indicator[data-v-0f09629d]{width:8px;height:8px;border-radius:50%;margin-right:5px}.status-indicator.connected[data-v-0f09629d]{background-color:#02f23e}.status-indicator.disconnected[data-v-0f09629d]{background-color:#f44336}.status-text[data-v-0f09629d]{font-size:14px;font-weight:400}.connected .status-text[data-v-0f09629d]{color:#02f23e}.disconnected .status-text[data-v-0f09629d]{color:#f44336}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 ce096ed..91e7c85 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1 +1 @@ -NEU小站课程评分系统 - v1.1
\ No newline at end of file +NEU小站课程评分系统
\ No newline at end of file diff --git a/dist/js/app.06c2471a.js b/dist/js/app.06c2471a.js deleted file mode 100644 index faa3210..0000000 --- a/dist/js/app.06c2471a.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){"use strict";var e={7958:function(e,t,s){var o=s(5130),a=s(6768);const n={key:0,class:"forbidden-container",style:{width:"135%"}},i={key:1,id:"app"},r={class:"sidebar"},c={class:"main-content"},l={key:2,class:"forbidden-container",style:{width:"122%"}};function d(e,t,s,o,d,u){const h=(0,a.g2)("SideBar"),m=(0,a.g2)("router-view");return(0,a.uX)(),(0,a.CE)("div",null,[d.isMobile&&!d.forceDesktopMode?((0,a.uX)(),(0,a.CE)("div",n,[t[1]||(t[1]=(0,a.Lk)("h1",{class:"forbidden-title"},"此系统暂不支持手机访问",-1)),t[2]||(t[2]=(0,a.Lk)("p",{class:"forbidden-text"},"推荐使用电脑访问此系统。",-1)),(0,a.Lk)("button",{onClick:t[0]||(t[0]=(...e)=>u.enableDesktopMode&&u.enableDesktopMode(...e)),class:"forbidden-back-btn"},"使用电脑版样式访问")])):d.isAuthorized?((0,a.uX)(),(0,a.CE)("div",i,[(0,a.Lk)("aside",r,[(0,a.bF)(h)]),(0,a.Lk)("main",c,[(0,a.bF)(m)])])):((0,a.uX)(),(0,a.CE)("div",l,t[3]||(t[3]=[(0,a.Fv)('

您的访问被拒绝

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

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

',4)])))])}function u(e,t,s,o,n,i){const r=(0,a.g2)("el-menu-item"),c=(0,a.g2)("el-menu");return(0,a.uX)(),(0,a.Wv)(c,{"default-active":i.activeMenu,class:"el-menu-vertical-demo","background-color":"#333","text-color":"#fff","active-text-color":"#ffd04b"},{default:(0,a.k6)((()=>[(0,a.bF)(r,{index:"1",onClick:t[0]||(t[0]=e=>i.goTo("home"))},{default:(0,a.k6)((()=>t[5]||(t[5]=[(0,a.Lk)("i",{class:"el-icon-house"},null,-1),(0,a.Lk)("span",null,"使用必看",-1)]))),_:1}),(0,a.bF)(r,{index:"2",onClick:t[1]||(t[1]=e=>i.goTo("rating"))},{default:(0,a.k6)((()=>t[6]||(t[6]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"选修课评分",-1)]))),_:1}),(0,a.bF)(r,{index:"3",onClick:t[2]||(t[2]=e=>i.goTo("ratingforcomp"))},{default:(0,a.k6)((()=>t[7]||(t[7]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"必修课评分",-1)]))),_:1}),(0,a.bF)(r,{index:"4",onClick:t[3]||(t[3]=e=>i.goTo("course-list"))},{default:(0,a.k6)((()=>t[8]||(t[8]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"我的课程",-1)]))),_:1}),(0,a.bF)(r,{index:"5",onClick:t[4]||(t[4]=e=>i.goTo("chat"))},{default:(0,a.k6)((()=>t[9]||(t[9]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"我的聊天",-1)]))),_:1}),t[10]||(t[10]=(0,a.Lk)("div",{class:"sidebar-footer"},[(0,a.Lk)("a",{href:"https://www.xn--xhq44jb2fzpc.com/",target:"_blank"},"点此返回NEU小站")],-1)),t[11]||(t[11]=(0,a.Lk)("div",{class:"footer-info"}," NEU小站课程评分系统 - v1.1 ",-1))])),_:1},8,["default-active"])}s(4114);var h={name:"SideBar",computed:{activeMenu(){const e=this.$route.name;return"home"===e?"1":"rating"===e?"2":"ratingforcomp"===e?"3":"course-list"===e?"4":"chat"===e?"5":"1"}},methods:{goTo(e){this.$router.push({name:e})}}},m=s(1241);const g=(0,m.A)(h,[["render",u],["__scopeId","data-v-474ac5cc"]]);var p=g,k={name:"App",data(){return{isAuthorized:!1,authChecked:!1,isMobile:!1,forceDesktopMode:!1}},components:{SideBar:p},mounted(){this.redirectToHTTPS(),this.checkIfMobile(),this.checkLoginStatus()},methods:{checkIfMobile(){const e=navigator.userAgent||navigator.vendor||window.opera,t=/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(e.toLowerCase()),s="true"===localStorage.getItem("forceDesktopMode");t&&!s?this.isMobile=!0:this.forceDesktopMode=s},enableDesktopMode(){this.forceDesktopMode=!0,localStorage.setItem("forceDesktopMode","true");const e=document.querySelector('meta[name="viewport"]');if(e)e.setAttribute("content","width=1024");else{const e=document.createElement("meta");e.name="viewport",e.content="width=1024",document.head.appendChild(e)}},async checkLoginStatus(){const e=document.cookie.split("; ").reduce(((e,t)=>{const[s,o]=t.split("=");return e[s]=decodeURIComponent(o),e}),{}).token;if(e)try{const t=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/qvphone",{method:"GET",headers:{Authorization:e}}),s=await t.json();t.ok&&"验证成功,用户已绑定手机号并完成激活。"===s.message?this.isAuthorized=!0:console.warn("用户未通过验证:",s.message)}catch(t){console.error("Error during phone verification:",t)}finally{this.authChecked=!0}},redirectToHTTPS(){if("localhost"!==location.hostname&&"127.0.0.1"!==location.hostname&&"http:"===location.protocol){const e=`https://${location.host}${location.pathname}${location.search}`;window.location.replace(e)}}}};const v=(0,m.A)(k,[["render",d]]);var C=v,b=s(6762),y=(s(4188),s(973)),f=s(4232);const L={key:0},w={id:"homepage-title"},_={key:1};function x(e,t,s,o,n,i){const r=(0,a.g2)("router-link");return n.isLoaded?((0,a.uX)(),(0,a.CE)("div",L,[(0,a.Lk)("div",null,[(0,a.Lk)("h2",w,(0,f.v_)(n.greeting)+", "+(0,f.v_)(n.nickname)+"!",1),t[9]||(t[9]=(0,a.Fv)('

• 2025.02.06 更新:新增AI课程总结功能,接入DeepSeek V3大模型。

• 2025.01.24 更新:评论区支持删除自己的评论。

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

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

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

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

',6)),(0,a.Lk)("p",null,[t[1]||(t[1]=(0,a.eW)(" 在创建课程时,请先了解课程的类别,以及课程的")),t[2]||(t[2]=(0,a.Lk)("strong",null,"开课院系",-1)),t[3]||(t[3]=(0,a.eW)(",")),(0,a.bF)(r,{to:"/courses?m=true",class:"guide-link"},{default:(0,a.k6)((()=>t[0]||(t[0]=[(0,a.eW)("点击此处")]))),_:1}),t[4]||(t[4]=(0,a.eW)("查看指引。")),t[5]||(t[5]=(0,a.Lk)("strong",null,'如果同一课程的任课教师不同,用户可以创建多个同名课程,例如"A老师-篮球"和"B老师-篮球"将被视为两个不同的课程。',-1)),t[6]||(t[6]=(0,a.eW)("创建的课程卡片")),t[7]||(t[7]=(0,a.Lk)("strong",null,"需经过管理员审核",-1)),t[8]||(t[8]=(0,a.eW)(',审核进度可在"我的课程"中实时查看。 '))]),t[10]||(t[10]=(0,a.Lk)("p",null,[(0,a.eW)(" 本系统鼓励同学们提供真实、有价值的评分。"),(0,a.Lk)("strong",null,"禁止发布带有侮辱性的人身攻击等恶意评论。"),(0,a.eW)("管理员将对恶意用户进行封禁处理,确保评分系统的文明环境。 ")],-1))])])):((0,a.uX)(),(0,a.CE)("div",_,t[11]||(t[11]=[(0,a.Lk)("p",null,"加载中,请稍后...",-1)])))}var E={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,o]=t.split("=");return e[s]=decodeURIComponent(o),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 S=(0,m.A)(E,[["render",x],["__scopeId","data-v-1720d549"]]);var P=S;const T={key:0,class:"loading-message"},M={key:1,class:"empty-message"},W={key:2,class:"course-table"},$={key:0},j=["onClick"],I={class:"pagination-bar"},X=["onClick"],D={class:"add-course"},U={class:"section-header"},F={class:"input-section"},A=["value"],N={key:3,class:"help-modal"},V={class:"help-modal-content"},z={class:"help-modal-header"};function O(e,t,s,n,i,r){const c=(0,a.g2)("CourseDetailModal");return(0,a.uX)(),(0,a.CE)("div",null,[t[14]||(t[14]=(0,a.Lk)("h2",null,"我添加的课程",-1)),i.isLoaded?0===i.submissions.length?((0,a.uX)(),(0,a.CE)("div",M," 您还没有添加任何课程。 ")):((0,a.uX)(),(0,a.CE)("div",W,[(0,a.Lk)("table",null,[t[7]||(t[7]=(0,a.Lk)("thead",null,[(0,a.Lk)("tr",null,[(0,a.Lk)("th",null,"课程名"),(0,a.Lk)("th",null,"分类"),(0,a.Lk)("th",null,"教师"),(0,a.Lk)("th",null,"开课院系"),(0,a.Lk)("th",null,"提交时间"),(0,a.Lk)("th",null,"状态更新时间"),(0,a.Lk)("th",null,"审核状态")])],-1)),(0,a.Lk)("tbody",null,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(r.paginatedSubmissions,(e=>((0,a.uX)(),(0,a.CE)("tr",{key:e.submit_id},[(0,a.Lk)("td",null,[0===e.course_id?((0,a.uX)(),(0,a.CE)("span",$,(0,f.v_)(e.course_name),1)):((0,a.uX)(),(0,a.CE)("span",{key:1,class:"clickable-text",onClick:t=>r.loadCourseDetail(e.course_id)},(0,f.v_)(e.course_name),9,j))]),(0,a.Lk)("td",null,(0,f.v_)(r.getCategoryName(e.category_id)),1),(0,a.Lk)("td",null,(0,f.v_)(e.teachers),1),(0,a.Lk)("td",null,(0,f.v_)(r.getCollegeName(e.college)),1),(0,a.Lk)("td",null,(0,f.v_)(r.formatTime(e.create_time)),1),(0,a.Lk)("td",null,(0,f.v_)(r.formatTime(e.status_update_time)),1),(0,a.Lk)("td",null,(0,f.v_)(e.status),1)])))),128))])]),(0,a.Lk)("div",I,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.totalPages,(e=>((0,a.uX)(),(0,a.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,f.C4)({active:i.currentPage===e})},(0,f.v_)(e),11,X)))),128))])])):((0,a.uX)(),(0,a.CE)("div",T," 加载中,请稍后... ")),(0,a.Lk)("div",D,[(0,a.Lk)("div",U,[t[9]||(t[9]=(0,a.Lk)("h2",null,"我要添加课程",-1)),(0,a.Lk)("button",{class:"help-btn",onClick:t[0]||(t[0]=e=>i.showHelp=!0)},t[8]||(t[8]=[(0,a.Lk)("span",{class:"help-icon"},"?",-1),(0,a.eW)(" 帮助 ")]))]),(0,a.Lk)("div",F,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.newCourseName=e),type:"text",placeholder:"请输入课程名称"},null,512),[[o.Jo,i.newCourseName]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[2]||(t[2]=e=>i.newCategoryId=e)},t[10]||(t[10]=[(0,a.Fv)('',14)]),512),[[o.u1,i.newCategoryId]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.newCollege=e)},[t[11]||(t[11]=(0,a.Lk)("option",{value:"",disabled:""},"请选择开课院系",-1)),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(r.filteredColleges,((e,t)=>((0,a.uX)(),(0,a.CE)("option",{key:t,value:t},(0,f.v_)(e),9,A)))),128))],512),[[o.u1,i.newCollege]]),(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.newTeachers=e),type:"text",placeholder:"请输入任课教师(多个教师之间用英文逗号,隔开)"},null,512),[[o.Jo,i.newTeachers]]),(0,a.Lk)("button",{onClick:t[5]||(t[5]=(...e)=>r.submitCourse&&r.submitCourse(...e))},"提交")])]),(0,a.bF)(c,{isVisible:i.showDetail,course:i.selectedCourse,onClose:r.closeCourseDetail},null,8,["isVisible","course","onClose"]),i.showHelp?((0,a.uX)(),(0,a.CE)("div",N,[(0,a.Lk)("div",V,[(0,a.Lk)("div",z,[t[12]||(t[12]=(0,a.Lk)("h3",null,"关于本系统课程信息的说明",-1)),(0,a.Lk)("button",{class:"close-btn",onClick:t[6]||(t[6]=e=>i.showHelp=!1)},"×")]),t[13]||(t[13]=(0,a.Fv)('

一些说明

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

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

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

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

1. 本人课程

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

2. 非本人课程

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

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

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

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

',1))])])):(0,a.Q3)("",!0)])}s(4979);const R={key:0,class:"modal-overlay"},q={class:"modal-content"},Q={class:"course-detail"},B={key:0,class:"share-modal"},J={key:1,class:"error-modal"},H={class:"rating-section"},K={class:"total-rating"},G={class:"progress-container"},Y={class:"stars"},Z=["onMouseover","onClick"],ee={class:"ai-summary"},te={key:0,class:"typing-cursor"},se={class:"comment-section"},oe={class:"sort-options"},ae={key:0,class:"comments-list"},ne={class:"comment-meta"},ie={class:"comment-time",style:{"margin-left":"10px"}},re=["onClick"],ce={style:{"margin-top":"8px"}},le={class:"comment-actions"},de={style:{color:"red"}},ue=["onClick"],he=["onClick"],me={key:1,class:"no-comments"},ge={key:2,class:"chat-modal-overlay"},pe={class:"chat-modal-content"},ke={class:"chat-modal-actions"},ve=["disabled"],Ce={key:3,class:"chat-modal-overlay"},be={class:"chat-modal-content"},ye={class:"chat-modal-actions"},fe={class:"new-comment"};function Le(e,t,s,n,i,r){const c=(0,a.g2)("el-progress");return s.isVisible?((0,a.uX)(),(0,a.CE)("div",R,[(0,a.Lk)("div",q,[(0,a.Lk)("span",{class:"close",onClick:t[0]||(t[0]=(...e)=>r.closeModal&&r.closeModal(...e))},"×"),(0,a.Lk)("div",Q,[(0,a.Lk)("h3",null,[(0,a.eW)((0,f.v_)(s.course.course_name)+" ",1),s.course.titles&&s.course.titles.length>0?((0,a.uX)(!0),(0,a.CE)(a.FK,{key:0},(0,a.pI)(s.course.titles,(e=>((0,a.uX)(),(0,a.CE)("span",{key:e.title,class:"course-title",style:(0,f.Tr)({borderColor:e.color,color:e.color})},(0,f.v_)(e.title),5)))),128)):(0,a.Q3)("",!0),(0,a.Lk)("button",{class:"share-btn",onClick:t[1]||(t[1]=(...e)=>r.shareCourse&&r.shareCourse(...e))},"分享给好友")]),(0,a.Lk)("p",null,[t[16]||(t[16]=(0,a.Lk)("strong",null,"分类:",-1)),(0,a.eW)(" "+(0,f.v_)(r.getCategoryName(s.course.category_id)),1)]),(0,a.Lk)("p",null,[t[17]||(t[17]=(0,a.Lk)("strong",null,"教师:",-1)),(0,a.eW)(" "+(0,f.v_)(s.course.teachers),1)]),(0,a.Lk)("p",null,[t[18]||(t[18]=(0,a.Lk)("strong",null,"开课院系:",-1)),(0,a.eW)(" "+(0,f.v_)(r.getCollegeName(s.course.college)),1)]),i.showShareModal?((0,a.uX)(),(0,a.CE)("div",B," 链接复制成功,快去分享给其他小伙伴吧! ")):(0,a.Q3)("",!0),i.showErrorModal?((0,a.uX)(),(0,a.CE)("div",J," 获取评论数据失败,正在刷新页面... ")):(0,a.Q3)("",!0),(0,a.Lk)("div",H,[(0,a.Lk)("h4",null,"课程实时平均分 ("+(0,f.v_)(s.course.rating_count)+"人评分)",1),(0,a.Lk)("div",K,(0,f.v_)(i.totalRating),1),(0,a.Lk)("div",G,[(0,a.bF)(c,{class:"progress",percentage:i.fiveStarPercent,status:"success","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("5星: "+(0,f.v_)(i.fiveStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(c,{class:"progress",percentage:i.fourStarPercent,status:"success","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("4星: "+(0,f.v_)(i.fourStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(c,{class:"progress",percentage:i.threeStarPercent,status:"warning","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("3星: "+(0,f.v_)(i.threeStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(c,{class:"progress",percentage:i.twoStarPercent,status:"warning","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("2星: "+(0,f.v_)(i.twoStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(c,{class:"progress",percentage:i.oneStarPercent,status:"exception","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("1星: "+(0,f.v_)(i.oneStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"])]),(0,a.Lk)("div",Y,[((0,a.uX)(),(0,a.CE)(a.FK,null,(0,a.pI)(5,(e=>(0,a.Lk)("span",{key:e,class:(0,f.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,Z))),64))])]),(0,a.Lk)("p",ee,[t[19]||(t[19]=(0,a.Lk)("span",{style:{display:"block","margin-bottom":"-15px"}},[(0,a.Lk)("strong",null,"AI课程总结"),(0,a.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,a.Lk)("span",{style:{"font-size":"12px","margin-left":"5px"}},[(0,a.eW)(" 内容由 "),(0,a.Lk)("img",{src:"https://download.东北大学.com/course_system/deepseek.svg",style:{height:"16px","vertical-align":"middle"}}),(0,a.eW)(" DeepSeek V3 生成,仅供参考 ")])],-1)),t[20]||(t[20]=(0,a.Lk)("br",null,null,-1)),i.displayedSummary?((0,a.uX)(),(0,a.CE)(a.FK,{key:0},[(0,a.eW)((0,f.v_)(i.displayedSummary),1),i.isTyping?((0,a.uX)(),(0,a.CE)("span",te,"|")):(0,a.Q3)("",!0)],64)):((0,a.uX)(),(0,a.CE)(a.FK,{key:1},[(0,a.eW)(" 当前课程的评分和评论数据过少,暂不能生成AI总结。 ")],64))])]),(0,a.Lk)("div",se,[(0,a.Lk)("div",oe,[(0,a.Lk)("label",null,[(0,a.bo)((0,a.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),[[o.XL,i.sortBy]]),t[21]||(t[21]=(0,a.eW)(" 赞数最多优先"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.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),[[o.XL,i.sortBy]]),t[22]||(t[22]=(0,a.eW)(" 最新评论优先"))])]),r.filteredComments?((0,a.uX)(),(0,a.CE)("div",ae,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.comments,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.comment_id,class:"comment"},[(0,a.Lk)("div",ne,[(0,a.Lk)("strong",null,(0,f.v_)(e.nickname),1),(0,a.Lk)("span",ie,"发表于 "+(0,f.v_)(r.formatTime(e.comment_time)),1),(0,a.Lk)("span",{class:(0,f.C4)(["like-section",{liked:e.is_liked}]),onClick:t=>r.toggleLike(e)}," ❤ "+(0,f.v_)(e.like_count),11,re)]),(0,a.Lk)("div",ce,(0,f.v_)(e.comment_content),1),(0,a.Lk)("div",le,[(0,a.Lk)("span",null,[t[23]||(t[23]=(0,a.eW)("评分: ")),(0,a.Lk)("strong",de,(0,f.v_)(e.rating),1)]),e.deleteable?((0,a.uX)(),(0,a.CE)("button",{key:0,onClick:t=>r.deleteComment(e.comment_id),class:"delete-btn"}," 删除 ",8,ue)):((0,a.uX)(),(0,a.CE)("button",{key:1,class:"chat-start-btn",onClick:t=>r.openChatModal(e.comment_id)}," 发起聊天 ",8,he))])])))),128))])):((0,a.uX)(),(0,a.CE)("p",me,"本课程暂无评论。")),i.isChatModalVisible?((0,a.uX)(),(0,a.CE)("div",ge,[(0,a.Lk)("div",pe,[(0,a.Lk)("span",{class:"chat-close-btn",onClick:t[7]||(t[7]=(...e)=>r.closeChatModal&&r.closeChatModal(...e))},"×"),t[24]||(t[24]=(0,a.Lk)("h3",null,"发起聊天",-1)),(0,a.bo)((0,a.Lk)("textarea",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.chatMessage=e),placeholder:"请输入聊天内容(至少6个字符)",class:"chat-textarea"},null,512),[[o.Jo,i.chatMessage]]),(0,a.Lk)("div",ke,[(0,a.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>r.submitChat&&r.submitChat(...e)),disabled:i.chatMessage.length<6},"发起",8,ve)])])])):(0,a.Q3)("",!0),i.isConversationExistsModalVisible?((0,a.uX)(),(0,a.CE)("div",Ce,[(0,a.Lk)("div",be,[(0,a.Lk)("span",{class:"chat-close-btn",onClick:t[10]||(t[10]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"×"),t[25]||(t[25]=(0,a.Lk)("h3",null,"在此课程下,您与此用户已有会话!",-1)),(0,a.Lk)("div",ye,[(0,a.Lk)("button",{onClick:t[11]||(t[11]=e=>r.navigateToConversation(i.existingConversationId))},"进入会话"),(0,a.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>r.closeConversationExistsModal&&r.closeConversationExistsModal(...e))},"取消")])])])):(0,a.Q3)("",!0),(0,a.Lk)("div",fe,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[13]||(t[13]=e=>i.nickname=e),placeholder:"推荐您起个有意义的昵称,如:被x老师伤透了心"},null,512),[[o.Jo,i.nickname]]),(0,a.bo)((0,a.Lk)("textarea",{"onUpdate:modelValue":t[14]||(t[14]=e=>i.commentContent=e),placeholder:"我们推荐您分享本课程的课程内容、学习难度、考核方式和给分好坏,以帮助更多同学做出判断。支持删除自己的评论。",style:{resize:"none",height:"50px"}},null,512),[[o.Jo,i.commentContent]]),(0,a.Lk)("button",{onClick:t[15]||(t[15]=(...e)=>r.submitComment&&r.submitComment(...e))},"提交评论")])])])])):(0,a.Q3)("",!0)}var we={props:{isVisible:{type:Boolean,required:!0},course:{type:Object,required:!0}},data(){return{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}},async mounted(){try{await Promise.all([this.fetchAndCacheEmail(),this.fetchRatingDistribution(),this.fetchUserRating()])}catch(e){console.error("Error loading data:",e)}},watch:{async course(e){if(e&&e.course_id){this.aiSummary=null,this.displayedSummary="",this.isTyping=!1;try{await Promise.all([this.fetchRatingDistribution(),this.fetchUserRating(),this.fetchComments(),this.fetchAISummary()])}catch(t){console.error("Error fetching course details:",t)}}},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:{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=this.getUserEmailFromCookie(),t=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-user-rating?user_email=${e}&course_id=${this.course.course_id}`);if(200===t.status){const e=await t.json();this.userRating=e.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=this.getUserEmailFromCookie(),s=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-rating",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:t,course_id:this.course.course_id,rating:e})});s.ok&&(this.fetchRatingDistribution(),this.fetchUserRating())},async typewriterEffect(e,t=30){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{const e=document.cookie.split("; ").find((e=>e.startsWith("token=")));if(!e)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);const t=e.split("=")[1],s=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-comments?course_id=${this.course.course_id}&sort_by=${this.sortBy}`,{headers:{Authorization:t}});if(403===s.status)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);if(404===s.status)return void(this.comments=[]);if(!s.ok)throw new Error("获取评论失败");const o=await s.json();this.comments=o.comments}catch(e){console.error("获取评论失败:",e),this.showErrorModal=!0,setTimeout((()=>{window.location.reload()}),2e3)}},async toggleLike(e){const t=this.getUserEmailFromCookie();e.is_liked?await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/unlike-comment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:t,comment_id:e.comment_id})}):await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/like-comment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:t,comment_id:e.comment_id})}),this.fetchComments()},async submitComment(){if(this.nickname.length<3||this.commentContent.length<6)return void alert("您的昵称请至少包含3个字符,评论请至少包含6个字符。");const e=this.getUserEmailFromCookie();await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-comment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:e,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(),o=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${o}-${a} ${n}:${i}`},async fetchAndCacheEmail(){if(this.cachedEmail)return;const e=document.cookie.split("; "),t=e.find((e=>e.startsWith("token="))),s=t?t.split("=")[1]:"";if(s)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:s}}),t=await e.json();e.ok&&t.email?this.cachedEmail=t.email:console.error("JWT验证失败或未找到邮箱")}catch(o){console.error("JWT验证时出错:",o)}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:document.cookie.split("; ").find((e=>e.startsWith("token="))).split("=")[1]},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=document.cookie.split("; ").find((e=>e.startsWith("token="))).split("=")[1],s=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/delete-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:t},body:JSON.stringify({comment_id:e})});if(s.ok)this.fetchComments();else{const e=await s.json();alert(e.error||"删除评论失败")}}catch(s){console.error("删除评论出错:",s),alert("删除评论失败")}}}};const _e=(0,m.A)(we,[["render",Le],["__scopeId","data-v-c515cfa2"]]);var xe=_e,Ee={components:{CourseDetailModal:xe},data(){return{submissions:[],newCourseName:"",newCategoryId:"",newTeachers:"",newCollege:"",currentPage:1,itemsPerPage:10,totalPages:1,isLoaded:!1,selectedCourse:null,showDetail:!1,cachedEmail:null,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:"资源与土木工程学院"},showHelp:!1}},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(){setTimeout((async()=>{this.isLoaded=!0,await this.fetchAndCacheEmail(),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.decodedParam=t,this.isValid=!0,this.loadCourseDetail(this.decodedParam))}catch(t){}},methods:{isPositiveInteger(e){const t=Number(e);return Number.isInteger(t)&&t>0},async fetchAndCacheEmail(){if(this.cachedEmail)return;const e=document.cookie.split("; "),t=e.find((e=>e.startsWith("token="))),s=t?t.split("=")[1]:"";if(s)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:s}}),t=await e.json();e.ok&&t.email?this.cachedEmail=t.email:console.error("JWT验证失败或未找到邮箱")}catch(o){console.error("JWT验证时出错:",o)}else console.error("未找到JWT信息")},async fetchSubmissions(){const e=this.getCookie("token");if(!e)return void alert("无法获取JWT,请重新登录。");const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/user/user-submissions",{method:"GET",headers:{"Content-Type":"application/json",Authorization:e}}),s=await t.json();200===t.status?(this.submissions=s,this.totalPages=Math.ceil(this.submissions.length/this.itemsPerPage)):alert(s.error||"查询投稿记录失败")},getCookie(e){const t=document.cookie.split(";");for(let s of t){const[t,o]=s.trim().split("=");if(t===e)return o}return null},goToPage(e){this.currentPage=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(),o=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${o}-${a} ${n}:${i}`},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},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 Se=(0,m.A)(Ee,[["render",O],["__scopeId","data-v-0b028aca"]]);var Pe=Se;const Te={key:0,class:"rating-page"},Me={class:"search-sort-bar"},We={class:"category-checkboxes"},$e=["value"],je={class:"course-cards"},Ie=["onClick"],Xe={class:"card-type"},De={class:"card-teachers"},Ue={class:"card-college"},Fe={class:"card-ratecount"},Ae={key:0,class:"card-topcomment"},Ne={key:1,class:"card-topcomment"},Ve={class:"card-rate"},ze={class:"pagination-bar"},Oe=["onClick"],Re=["disabled"],qe={key:1};function Qe(e,t,s,n,i,r){const c=(0,a.g2)("CourseDetailModal");return i.isLoaded?((0,a.uX)(),(0,a.CE)("div",Te,[t[30]||(t[30]=(0,a.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,a.Lk)("div",Me,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"请输入课程名"},null,512),[[o.Jo,i.searchQuery]]),(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",style:{width:"450px"},placeholder:"请输入教师名,多个教师以英文逗号分隔,如“张三,李四”"},null,512),[[o.Jo,i.teacherQuery]]),(0,a.Lk)("div",We,[(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:"1"},null,512),[[o.lH,i.selectedCategories]]),t[15]||(t[15]=(0,a.eW)(" 通识选修类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[3]||(t[3]=e=>i.selectedCategories=e),value:"2"},null,512),[[o.lH,i.selectedCategories]]),t[16]||(t[16]=(0,a.eW)(" 人文选修类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCategories=e),value:"3"},null,512),[[o.lH,i.selectedCategories]]),t[17]||(t[17]=(0,a.eW)(" 专业方向类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[5]||(t[5]=e=>i.selectedCategories=e),value:"4"},null,512),[[o.lH,i.selectedCategories]]),t[18]||(t[18]=(0,a.eW)(" 体育类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[6]||(t[6]=e=>i.selectedCategories=e),value:"5"},null,512),[[o.lH,i.selectedCategories]]),t[19]||(t[19]=(0,a.eW)(" 学科基础类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[7]||(t[7]=e=>i.selectedCategories=e),value:"6"},null,512),[[o.lH,i.selectedCategories]]),t[20]||(t[20]=(0,a.eW)(" 暑期国际课"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[8]||(t[8]=e=>i.selectedCategories=e),value:"7"},null,512),[[o.lH,i.selectedCategories]]),t[21]||(t[21]=(0,a.eW)(" 数学与自然科学类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[9]||(t[9]=e=>i.selectedCategories=e),value:"8"},null,512),[[o.lH,i.selectedCategories]]),t[22]||(t[22]=(0,a.eW)(" 重修专栏"))])]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[10]||(t[10]=e=>i.sortBy=e)},t[23]||(t[23]=[(0,a.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,a.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,a.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[o.u1,i.sortBy]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[11]||(t[11]=e=>i.selectedCollege=e)},[t[24]||(t[24]=(0,a.Lk)("option",{value:""},"不限院系",-1)),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(r.filteredColleges,(([e,t])=>((0,a.uX)(),(0,a.CE)("option",{key:e,value:e},(0,f.v_)(t),9,$e)))),128))],512),[[o.u1,i.selectedCollege]]),(0,a.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>r.searchCourses&&r.searchCourses(...e))},"更新查询")]),(0,a.Lk)("div",je,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.courses,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>r.showCourseDetail(e)},[(0,a.Lk)("h3",null,[(0,a.eW)((0,f.v_)(e.course_name)+" ",1),e.titles&&e.titles.length>0?((0,a.uX)(!0),(0,a.CE)(a.FK,{key:0},(0,a.pI)(e.titles,(e=>((0,a.uX)(),(0,a.CE)("span",{key:e.title,class:"course-title",style:(0,f.Tr)({borderColor:e.color,color:e.color})},(0,f.v_)(e.title),5)))),128)):(0,a.Q3)("",!0)]),(0,a.Lk)("p",Xe,[t[25]||(t[25]=(0,a.Lk)("strong",null,"分类:",-1)),(0,a.eW)(" "+(0,f.v_)(r.getCategoryName(e.category_id)),1)]),(0,a.Lk)("p",De,[t[26]||(t[26]=(0,a.Lk)("strong",null,"教师:",-1)),(0,a.eW)(" "+(0,f.v_)(e.teachers),1)]),(0,a.Lk)("p",Ue,[t[27]||(t[27]=(0,a.Lk)("strong",null,"开课院系:",-1)),(0,a.eW)(" "+(0,f.v_)(r.getCollegeName(e.college)),1)]),(0,a.Lk)("p",Fe,[t[28]||(t[28]=(0,a.Lk)("strong",null,"评分人数:",-1)),(0,a.eW)(" "+(0,f.v_)(e.rating_count),1)]),e.top_comment?((0,a.uX)(),(0,a.CE)("p",Ae,'"'+(0,f.v_)(r.formatTopComment(e.top_comment))+'"',1)):((0,a.uX)(),(0,a.CE)("p",Ne,"暂无评论")),(0,a.Lk)("p",Ve,[(0,a.eW)((0,f.v_)(e.rating),1),t[29]||(t[29]=(0,a.Lk)("span",{class:"unit"}," 分",-1))])],8,Ie)))),128))]),(0,a.Lk)("div",ze,[(0,a.Lk)("button",{onClick:t[13]||(t[13]=e=>r.goToPage(1)),class:(0,f.C4)({active:1===i.currentPage})},"首页",2),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(r.getPaginationPages(),(e=>((0,a.uX)(),(0,a.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,f.C4)({active:i.currentPage===e})},(0,f.v_)(e),11,Oe)))),128)),(0,a.Lk)("button",{onClick:t[14]||(t[14]=e=>r.goToPage(i.totalPages)),class:(0,f.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,Re)]),(0,a.bF)(c,{isVisible:i.showDetail,course:i.selectedCourse,onClose:r.closeCourseDetail},null,8,["isVisible","course","onClose"])])):((0,a.uX)(),(0,a.CE)("div",qe,t[31]||(t[31]=[(0,a.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var Be={components:{CourseDetailModal:xe},data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,showDetail:!1,selectedCourse:null,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],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(){setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},methods:{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}`:"",o=encodeURIComponent(this.searchQuery),a=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${o}&teacher=${a}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i},async fetchTotalPages(){const e=0===this.selectedCategories.length?"1,2,3,4,5,6,7,8":this.selectedCategories.join(","),t=this.selectedCollege?`&college=${this.selectedCollege}`:"",s=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),a=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses/pages?search=${s}&teacher=${o}&category=${e}${t}`),n=await a.json();this.totalPages=n.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,o=10;if(t<=o)for(let a=1;a<=t;a++)e.push(a);else{let o=Math.max(s-5,1),a=Math.min(s+4,t);s<=6&&(o=1,a=10),s>=t-4&&(o=t-9,a=t);for(let t=o;t<=a;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses(),this.fetchTotalPages()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){this.selectedCourse={...e},this.showDetail=!0},formatTopComment(e){if(!e)return"";let t=0,s="";for(let o=0;o255?1:.5;if(t+a>29)return s+"...";t+=a,s+=e[o]}return s},closeCourseDetail(){this.showDetail=!1,this.selectedCourse=null},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 Je=(0,m.A)(Be,[["render",Qe],["__scopeId","data-v-392e0a1a"]]);var He=Je;const Ke={key:0,class:"rating-page"},Ge={class:"search-sort-bar"},Ye={class:"category-checkboxes"},Ze={class:"select-container"},et=["value"],tt={class:"course-cards"},st=["onClick"],ot={class:"card-type"},at={class:"card-teachers"},nt={class:"card-college"},it={class:"card-ratecount"},rt={key:0,class:"card-topcomment"},ct={key:1,class:"card-topcomment"},lt={class:"card-rate"},dt={class:"pagination-bar"},ut=["onClick"],ht=["disabled"],mt={key:1};function gt(e,t,s,n,i,r){const c=(0,a.g2)("CourseDetailModal");return i.isLoaded?((0,a.uX)(),(0,a.CE)("div",Ke,[t[24]||(t[24]=(0,a.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,a.Lk)("div",Ge,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"请输入课程名"},null,512),[[o.Jo,i.searchQuery]]),(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",style:{width:"450px"},placeholder:"请输入教师名,多个教师以英文逗号分隔,如“张三,李四”"},null,512),[[o.Jo,i.teacherQuery]]),(0,a.Lk)("div",Ye,[(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:"9"},null,512),[[o.lH,i.selectedCategories]]),t[12]||(t[12]=(0,a.eW)(" 数学与自然科学类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[3]||(t[3]=e=>i.selectedCategories=e),value:"10"},null,512),[[o.lH,i.selectedCategories]]),t[13]||(t[13]=(0,a.eW)(" 人文社会科学类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCategories=e),value:"11"},null,512),[[o.lH,i.selectedCategories]]),t[14]||(t[14]=(0,a.eW)(" 学科基础类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[5]||(t[5]=e=>i.selectedCategories=e),value:"12"},null,512),[[o.lH,i.selectedCategories]]),t[15]||(t[15]=(0,a.eW)(" 专业方向类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[6]||(t[6]=e=>i.selectedCategories=e),value:"13"},null,512),[[o.lH,i.selectedCategories]]),t[16]||(t[16]=(0,a.eW)(" 实践类"))])]),(0,a.Lk)("div",Ze,[(0,a.bo)((0,a.Lk)("select",{class:"sortBySelect","onUpdate:modelValue":t[7]||(t[7]=e=>i.sortBy=e)},t[17]||(t[17]=[(0,a.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,a.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,a.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[o.u1,i.sortBy]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.selectedCollege=e)},[t[18]||(t[18]=(0,a.Lk)("option",{value:""},"不限院系",-1)),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(r.filteredColleges,(([e,t])=>((0,a.uX)(),(0,a.CE)("option",{key:e,value:e},(0,f.v_)(t),9,et)))),128))],512),[[o.u1,i.selectedCollege]])]),(0,a.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>r.searchCourses&&r.searchCourses(...e))},"更新查询")]),(0,a.Lk)("div",tt,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.courses,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>r.showCourseDetail(e)},[(0,a.Lk)("h3",null,[(0,a.eW)((0,f.v_)(e.course_name)+" ",1),e.titles&&e.titles.length>0?((0,a.uX)(!0),(0,a.CE)(a.FK,{key:0},(0,a.pI)(e.titles,(e=>((0,a.uX)(),(0,a.CE)("span",{key:e.title,class:"course-title",style:(0,f.Tr)({borderColor:e.color,color:e.color})},(0,f.v_)(e.title),5)))),128)):(0,a.Q3)("",!0)]),(0,a.Lk)("p",ot,[t[19]||(t[19]=(0,a.Lk)("strong",null,"分类:",-1)),(0,a.eW)(" "+(0,f.v_)(r.getCategoryName(e.category_id)),1)]),(0,a.Lk)("p",at,[t[20]||(t[20]=(0,a.Lk)("strong",null,"教师:",-1)),(0,a.eW)(" "+(0,f.v_)(e.teachers),1)]),(0,a.Lk)("p",nt,[t[21]||(t[21]=(0,a.Lk)("strong",null,"开课院系:",-1)),(0,a.eW)(" "+(0,f.v_)(r.getCollegeName(e.college)),1)]),(0,a.Lk)("p",it,[t[22]||(t[22]=(0,a.Lk)("strong",null,"评分人数:",-1)),(0,a.eW)(" "+(0,f.v_)(e.rating_count),1)]),e.top_comment?((0,a.uX)(),(0,a.CE)("p",rt,'"'+(0,f.v_)(r.formatTopComment(e.top_comment))+'"',1)):((0,a.uX)(),(0,a.CE)("p",ct,"暂无评论")),(0,a.Lk)("p",lt,[(0,a.eW)((0,f.v_)(e.rating),1),t[23]||(t[23]=(0,a.Lk)("span",{class:"unit"}," 分",-1))])],8,st)))),128))]),(0,a.Lk)("div",dt,[(0,a.Lk)("button",{onClick:t[10]||(t[10]=e=>r.goToPage(1)),class:(0,f.C4)({active:1===i.currentPage})},"首页",2),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(r.getPaginationPages(),(e=>((0,a.uX)(),(0,a.CE)("button",{key:e,onClick:t=>r.goToPage(e),class:(0,f.C4)({active:i.currentPage===e})},(0,f.v_)(e),11,ut)))),128)),(0,a.Lk)("button",{onClick:t[11]||(t[11]=e=>r.goToPage(i.totalPages)),class:(0,f.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,ht)]),(0,a.bF)(c,{isVisible:i.showDetail,course:i.selectedCourse,onClose:r.closeCourseDetail},null,8,["isVisible","course","onClose"])])):((0,a.uX)(),(0,a.CE)("div",mt,t[25]||(t[25]=[(0,a.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var pt={components:{CourseDetailModal:xe},data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,showDetail:!1,selectedCourse:null,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],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(){setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},methods:{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}`:"",o=encodeURIComponent(this.searchQuery),a=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${o}&teacher=${a}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i},async fetchTotalPages(){const e=0===this.selectedCategories.length?"9,10,11,12,13":this.selectedCategories.join(","),t=this.selectedCollege?`&college=${this.selectedCollege}`:"",s=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),a=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses/pages?search=${s}&teacher=${o}&category=${e}${t}`),n=await a.json();this.totalPages=n.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,o=10;if(t<=o)for(let a=1;a<=t;a++)e.push(a);else{let o=Math.max(s-5,1),a=Math.min(s+4,t);s<=6&&(o=1,a=10),s>=t-4&&(o=t-9,a=t);for(let t=o;t<=a;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses(),this.fetchTotalPages()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){this.selectedCourse={...e},this.showDetail=!0},formatTopComment(e){if(!e)return"";let t=0,s="";for(let o=0;o255?1:.5;if(t+a>29)return s+"...";t+=a,s+=e[o]}return s},closeCourseDetail(){this.showDetail=!1,this.selectedCourse=null},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 kt=(0,m.A)(pt,[["render",gt],["__scopeId","data-v-22fe0ea1"]]);var vt=kt;const Ct={class:"chat-page"},bt={class:"sidebar"},yt={class:"header"},ft={class:"status-text"},Lt={key:0,class:"no-conversations"},wt=["onClick"],_t={class:"conversation-name"},xt={key:0,class:"new-message-label"},Et={class:"conversation-updated-at"},St={class:"conversation-last-message"},Pt={class:"chat-container"},Tt={class:"conversation-info"},Mt={class:"message-bubble"},Wt={key:0},$t={class:"input-container"};function jt(e,t,s,o,n,i){const r=(0,a.g2)("el-scrollbar"),c=(0,a.g2)("el-button"),l=(0,a.g2)("el-input"),d=(0,a.g2)("el-tooltip"),u=(0,a.g2)("CourseDetailModal");return(0,a.uX)(),(0,a.CE)("div",Ct,[(0,a.Lk)("div",bt,[(0,a.Lk)("h3",yt,[t[2]||(t[2]=(0,a.eW)(" 会话列表 ")),(0,a.Lk)("span",{class:(0,f.C4)(["connection-status",{connected:n.isConnected,disconnected:!n.isConnected}])},[(0,a.Lk)("span",{class:(0,f.C4)(["status-indicator",{connected:n.isConnected,disconnected:!n.isConnected}])},null,2),(0,a.Lk)("span",ft,(0,f.v_)(n.isConnected?"即时聊天已连接":"即时聊天已断开,正在重新连接..."),1)],2)]),(0,a.bF)(r,null,{default:(0,a.k6)((()=>[0===n.conversations.length?((0,a.uX)(),(0,a.CE)("div",Lt," 还没有会话,快去通过评论发起聊天吧! ")):((0,a.uX)(!0),(0,a.CE)(a.FK,{key:1},(0,a.pI)(n.conversations,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.conversation_id,class:(0,f.C4)(["conversation-item",e.conversation_id===n.activeConversation?"active":""]),onClick:t=>i.selectConversation(e.conversation_id)},[(0,a.Lk)("div",_t,[(0,a.eW)((0,f.v_)(e.course_name)+" ",1),(0,a.Lk)("span",{class:(0,f.C4)(["role-label",{owner:"owner"===e.role,member:"member"===e.role}])},(0,f.v_)("owner"===e.role?"我发起的":"我收到的"),3),e.is_read?(0,a.Q3)("",!0):((0,a.uX)(),(0,a.CE)("span",xt,"新消息"))]),(0,a.Lk)("small",Et,"更新时间: "+(0,f.v_)(i.formatDate(e.updated_at)),1),t[3]||(t[3]=(0,a.Lk)("br",null,null,-1)),(0,a.Lk)("small",St,(0,f.v_)(e.latest_sender?"我:":"对方:")+(0,f.v_)(e.content||"还没有消息哦,快去通过某条课程评论发起聊天吧!"),1)],10,wt)))),128))])),_:1})]),(0,a.Lk)("div",Pt,[(0,a.Lk)("div",Tt,[(0,a.Lk)("span",null,(0,f.v_)(null!==n.rating?"该用户对课程评分为 "+n.rating.toFixed(1):"该用户暂未对课程进行评分"),1),(0,a.bF)(c,{onClick:t[0]||(t[0]=e=>i.loadCourseDetail(n.selectedCourseId))},{default:(0,a.k6)((()=>t[4]||(t[4]=[(0,a.eW)("查看课程")]))),_:1})]),(0,a.bF)(r,{ref:"messageScrollbar",class:"message-list"},{default:(0,a.k6)((()=>[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(n.messages,((e,t)=>((0,a.uX)(),(0,a.CE)("div",{key:t,class:(0,f.C4)(["message",1===e.sender?"self":"other"])},[(0,a.Lk)("div",Mt,[(0,a.Lk)("span",null,(0,f.v_)(e.content),1),(0,a.Lk)("div",{class:(0,f.C4)(["message-info",1===e.sender?"align-right":"align-left"])},[(0,a.Lk)("small",null,(0,f.v_)(i.formatDate(e.created_at)),1),1===e.sender?((0,a.uX)(),(0,a.CE)("small",Wt,(0,f.v_)(e.is_read?"已读":"未读"),1)):(0,a.Q3)("",!0)],2)])],2)))),128))])),_:1},512),(0,a.Lk)("div",$t,[(0,a.bF)(l,{modelValue:n.newMessage,"onUpdate:modelValue":t[1]||(t[1]=e=>n.newMessage=e),type:"textarea",rows:"2",placeholder:"请输入您的消息,按Enter换行,Ctrl+Enter发送。",class:"locked-input",onKeydown:i.handleKeyDown},null,8,["modelValue","onKeydown"]),(0,a.bF)(d,{content:"Ctrl + Enter",placement:"top"},{default:(0,a.k6)((()=>[(0,a.bF)(c,{onClick:i.sendMessage,type:"primary"},{default:(0,a.k6)((()=>t[5]||(t[5]=[(0,a.eW)("发送")]))),_:1},8,["onClick"])])),_:1})])]),(0,a.bF)(u,{isVisible:n.showDetail,course:n.selectedCourse,onClose:i.closeCourseDetail},null,8,["isVisible","course","onClose"])])}var It=s(4373),Xt={components:{CourseDetailModal:xe},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 It.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 It.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 It.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 It.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 Dt=(0,m.A)(Xt,[["render",jt],["__scopeId","data-v-0f09629d"]]);var Ut=Dt;const Ft=[{path:"/",name:"home",meta:{title:"NEU小站课程评分系统 - v1.1"},component:P},{path:"/courses",name:"course-list",meta:{title:"我的课程 - NEU小站课程评分系统 - v1.1"},component:Pe},{path:"/rating",name:"rating",meta:{title:"选修课列表 - NEU小站课程评分系统 - v1.1"},component:He},{path:"/ratingforcomp",name:"ratingforcomp",meta:{title:"必修课列表 - NEU小站课程评分系统 - v1.1"},component:vt},{path:"/chat",name:"chat",meta:{title:"我的聊天 - NEU小站课程评分系统 - v1.1"},component:Ut}],At=(0,y.aE)({history:(0,y.LA)(),routes:Ft});At.beforeEach(((e,t,s)=>{document.title=e.meta.title||"默认标题",s()}));var Nt=At;const Vt=(0,o.Ef)(C);Vt.use(Nt),Vt.use(b.A),Vt.mount("#app"),It.A.defaults.baseURL="https://coursesystem.xn--xhq44jb2fzpc.com/",Vt.config.globalProperties.$axios=It.A}},t={};function s(o){var a=t[o];if(void 0!==a)return a.exports;var n=t[o]={exports:{}};return e[o].call(n.exports,n,n.exports,s),n.exports}s.m=e,function(){var e=[];s.O=function(t,o,a,n){if(!o){var i=1/0;for(d=0;d=n)&&Object.keys(s.O).every((function(e){return s.O[e](o[c])}))?o.splice(c--,1):(r=!1,n0&&e[d-1][2]>n;d--)e[d]=e[d-1];e[d]=[o,a,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 o in t)s.o(t,o)&&!s.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})}}(),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,o){var a,n,i=o[0],r=o[1],c=o[2],l=0;if(i.some((function(t){return 0!==e[t]}))){for(a in r)s.o(r,a)&&(s.m[a]=r[a]);if(c)var d=c(s)}for(t&&t(o);ld.enableDesktopMode&&d.enableDesktopMode(...e)),class:"forbidden-back-btn"},"使用电脑版样式访问")])):u.isAuthorized?((0,a.uX)(),(0,a.CE)("div",i,[(0,a.Lk)("aside",l,[(0,a.bF)(h)]),(0,a.Lk)("main",r,[(0,a.bF)(m)])])):((0,a.uX)(),(0,a.CE)("div",c,t[3]||(t[3]=[(0,a.Fv)('

您的访问被拒绝

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

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

',4)])))])}function d(e,t,s,o,n,i){const l=(0,a.g2)("el-menu-item"),r=(0,a.g2)("el-menu");return(0,a.uX)(),(0,a.Wv)(r,{"default-active":i.activeMenu,class:"el-menu-vertical-demo","background-color":"#333","text-color":"#fff","active-text-color":"#ffd04b"},{default:(0,a.k6)((()=>[(0,a.bF)(l,{index:"1",onClick:t[0]||(t[0]=e=>i.goTo("home"))},{default:(0,a.k6)((()=>t[6]||(t[6]=[(0,a.Lk)("i",{class:"el-icon-house"},null,-1),(0,a.Lk)("span",null,"使用必看",-1)]))),_:1}),(0,a.bF)(l,{index:"2",onClick:t[1]||(t[1]=e=>i.goTo("rating"))},{default:(0,a.k6)((()=>t[7]||(t[7]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"选修课评分",-1)]))),_:1}),(0,a.bF)(l,{index:"3",onClick:t[2]||(t[2]=e=>i.goTo("ratingforcomp"))},{default:(0,a.k6)((()=>t[8]||(t[8]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"必修课评分",-1)]))),_:1}),(0,a.bF)(l,{index:"4",onClick:t[3]||(t[3]=e=>i.goTo("course-list"))},{default:(0,a.k6)((()=>t[9]||(t[9]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"我的课程",-1)]))),_:1}),(0,a.bF)(l,{index:"5",onClick:t[4]||(t[4]=e=>i.goTo("chat"))},{default:(0,a.k6)((()=>t[10]||(t[10]=[(0,a.Lk)("i",{class:"el-icon-setting"},null,-1),(0,a.Lk)("span",null,"我的聊天",-1)]))),_:1}),(0,a.bF)(l,{index:"6",onClick:t[5]||(t[5]=e=>i.goTo("about"))},{default:(0,a.k6)((()=>t[11]||(t[11]=[(0,a.Lk)("i",{class:"el-icon-info"},null,-1),(0,a.Lk)("span",null,"关于",-1)]))),_:1}),t[12]||(t[12]=(0,a.Lk)("div",{class:"sidebar-footer"},[(0,a.Lk)("span",{class:"footer-title"},"NEU小站课程评分系统 - v1.1"),(0,a.Lk)("div",{class:"footer-info"},[(0,a.eW)(" © 2025 "),(0,a.Lk)("a",{href:"https://www.xn--xhq44jb2fzpc.com/",target:"_blank"},"NEU小站")])],-1))])),_:1},8,["default-active"])}s(4114);var h={name:"SideBar",computed:{activeMenu(){const e=this.$route.name;return"home"===e?"1":"rating"===e?"2":"ratingforcomp"===e?"3":"course-list"===e?"4":"chat"===e?"5":"about"===e?"6":"1"}},methods:{goTo(e){this.$router.push({name:e})}}},m=s(1241);const g=(0,m.A)(h,[["render",d],["__scopeId","data-v-fa32c4be"]]);var p=g,k={name:"App",data(){return{isAuthorized:!1,authChecked:!1,isMobile:!1,forceDesktopMode:!1}},components:{SideBar:p},mounted(){this.redirectToHTTPS(),this.checkIfMobile(),this.checkLoginStatus()},methods:{checkIfMobile(){const e=navigator.userAgent||navigator.vendor||window.opera,t=/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(e.toLowerCase()),s="true"===localStorage.getItem("forceDesktopMode");t&&!s?this.isMobile=!0:this.forceDesktopMode=s},enableDesktopMode(){this.forceDesktopMode=!0,localStorage.setItem("forceDesktopMode","true");const e=document.querySelector('meta[name="viewport"]');if(e)e.setAttribute("content","width=1024");else{const e=document.createElement("meta");e.name="viewport",e.content="width=1024",document.head.appendChild(e)}},async checkLoginStatus(){const e=document.cookie.split("; ").reduce(((e,t)=>{const[s,o]=t.split("=");return e[s]=decodeURIComponent(o),e}),{}).token;if(e)try{const t=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/qvphone",{method:"GET",headers:{Authorization:e}}),s=await t.json();t.ok&&"验证成功,用户已绑定手机号并完成激活。"===s.message?this.isAuthorized=!0:console.warn("用户未通过验证:",s.message)}catch(t){console.error("Error during phone verification:",t)}finally{this.authChecked=!0}},redirectToHTTPS(){if("localhost"!==location.hostname&&"127.0.0.1"!==location.hostname&&"http:"===location.protocol){const e=`https://${location.host}${location.pathname}${location.search}`;window.location.replace(e)}}}};const v=(0,m.A)(k,[["render",u]]);var C=v,b=s(6762),y=(s(4188),s(973)),f=s(4232);const L={key:0},_={id:"homepage-title"},w={key:1};function E(e,t,s,o,n,i){const l=(0,a.g2)("router-link");return n.isLoaded?((0,a.uX)(),(0,a.CE)("div",L,[(0,a.Lk)("div",null,[(0,a.Lk)("h2",_,(0,f.v_)(n.greeting)+", "+(0,f.v_)(n.nickname)+"!",1),t[9]||(t[9]=(0,a.Fv)("

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

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

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

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

",4)),(0,a.Lk)("p",null,[t[1]||(t[1]=(0,a.eW)(" 在创建课程时,请先了解课程的类别,以及课程的")),t[2]||(t[2]=(0,a.Lk)("strong",null,"开课院系",-1)),t[3]||(t[3]=(0,a.eW)(",")),(0,a.bF)(l,{to:"/courses?m=true",class:"guide-link"},{default:(0,a.k6)((()=>t[0]||(t[0]=[(0,a.eW)("点击此处")]))),_:1}),t[4]||(t[4]=(0,a.eW)("查看指引。")),t[5]||(t[5]=(0,a.Lk)("strong",null,'如果同一课程的任课教师不同,用户可以创建多个同名课程,例如"A老师-篮球"和"B老师-篮球"将被视为两个不同的课程。',-1)),t[6]||(t[6]=(0,a.eW)("创建的课程卡片")),t[7]||(t[7]=(0,a.Lk)("strong",null,"需经过管理员审核",-1)),t[8]||(t[8]=(0,a.eW)(',审核进度可在"我的课程"中实时查看。 '))]),t[10]||(t[10]=(0,a.Lk)("p",null,[(0,a.eW)(" 本系统鼓励同学们提供真实、有价值的评分。"),(0,a.Lk)("strong",null,"禁止发布带有侮辱性的人身攻击等恶意评论。"),(0,a.eW)("管理员将对恶意用户进行封禁处理,确保评分系统的文明环境。 ")],-1))])])):((0,a.uX)(),(0,a.CE)("div",w,t[11]||(t[11]=[(0,a.Lk)("p",null,"加载中,请稍后...",-1)])))}var x={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,o]=t.split("=");return e[s]=decodeURIComponent(o),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 S=(0,m.A)(x,[["render",E],["__scopeId","data-v-b83355ba"]]);var P=S;const T={key:0,class:"loading-message"},M={key:1,class:"empty-message"},W={key:2,class:"course-table"},j={key:0},I=["onClick"],$={class:"pagination-bar"},F=["onClick"],X={class:"add-course"},U={class:"section-header"},D={class:"input-section"},N=["value"],A={key:3,class:"help-modal"},V={class:"help-modal-content"},z={class:"help-modal-header"};function O(e,t,s,n,i,l){const r=(0,a.g2)("CourseDetailModal");return(0,a.uX)(),(0,a.CE)("div",null,[t[14]||(t[14]=(0,a.Lk)("h2",null,"我添加的课程",-1)),i.isLoaded?0===i.submissions.length?((0,a.uX)(),(0,a.CE)("div",M," 您还没有添加任何课程。 ")):((0,a.uX)(),(0,a.CE)("div",W,[(0,a.Lk)("table",null,[t[7]||(t[7]=(0,a.Lk)("thead",null,[(0,a.Lk)("tr",null,[(0,a.Lk)("th",null,"课程名"),(0,a.Lk)("th",null,"分类"),(0,a.Lk)("th",null,"教师"),(0,a.Lk)("th",null,"开课院系"),(0,a.Lk)("th",null,"提交时间"),(0,a.Lk)("th",null,"状态更新时间"),(0,a.Lk)("th",null,"审核状态")])],-1)),(0,a.Lk)("tbody",null,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(l.paginatedSubmissions,(e=>((0,a.uX)(),(0,a.CE)("tr",{key:e.submit_id},[(0,a.Lk)("td",null,[0===e.course_id?((0,a.uX)(),(0,a.CE)("span",j,(0,f.v_)(e.course_name),1)):((0,a.uX)(),(0,a.CE)("span",{key:1,class:"clickable-text",onClick:t=>l.loadCourseDetail(e.course_id)},(0,f.v_)(e.course_name),9,I))]),(0,a.Lk)("td",null,(0,f.v_)(l.getCategoryName(e.category_id)),1),(0,a.Lk)("td",null,(0,f.v_)(e.teachers),1),(0,a.Lk)("td",null,(0,f.v_)(l.getCollegeName(e.college)),1),(0,a.Lk)("td",null,(0,f.v_)(l.formatTime(e.create_time)),1),(0,a.Lk)("td",null,(0,f.v_)(l.formatTime(e.status_update_time)),1),(0,a.Lk)("td",null,(0,f.v_)(e.status),1)])))),128))])]),(0,a.Lk)("div",$,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.totalPages,(e=>((0,a.uX)(),(0,a.CE)("button",{key:e,onClick:t=>l.goToPage(e),class:(0,f.C4)({active:i.currentPage===e})},(0,f.v_)(e),11,F)))),128))])])):((0,a.uX)(),(0,a.CE)("div",T," 加载中,请稍后... ")),(0,a.Lk)("div",X,[(0,a.Lk)("div",U,[t[9]||(t[9]=(0,a.Lk)("h2",null,"我要添加课程",-1)),(0,a.Lk)("button",{class:"help-btn",onClick:t[0]||(t[0]=e=>i.showHelp=!0)},t[8]||(t[8]=[(0,a.Lk)("span",{class:"help-icon"},"?",-1),(0,a.eW)(" 帮助 ")]))]),(0,a.Lk)("div",D,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.newCourseName=e),type:"text",placeholder:"请输入课程名称"},null,512),[[o.Jo,i.newCourseName]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[2]||(t[2]=e=>i.newCategoryId=e)},t[10]||(t[10]=[(0,a.Fv)('',14)]),512),[[o.u1,i.newCategoryId]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[3]||(t[3]=e=>i.newCollege=e)},[t[11]||(t[11]=(0,a.Lk)("option",{value:"",disabled:""},"请选择开课院系",-1)),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(l.filteredColleges,((e,t)=>((0,a.uX)(),(0,a.CE)("option",{key:t,value:t},(0,f.v_)(e),9,N)))),128))],512),[[o.u1,i.newCollege]]),(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[4]||(t[4]=e=>i.newTeachers=e),type:"text",placeholder:"请输入任课教师(多个教师之间用英文逗号,隔开)"},null,512),[[o.Jo,i.newTeachers]]),(0,a.Lk)("button",{onClick:t[5]||(t[5]=(...e)=>l.submitCourse&&l.submitCourse(...e))},"提交")])]),(0,a.bF)(r,{isVisible:i.showDetail,course:i.selectedCourse,onClose:l.closeCourseDetail},null,8,["isVisible","course","onClose"]),i.showHelp?((0,a.uX)(),(0,a.CE)("div",A,[(0,a.Lk)("div",V,[(0,a.Lk)("div",z,[t[12]||(t[12]=(0,a.Lk)("h3",null,"关于本系统课程信息的说明",-1)),(0,a.Lk)("button",{class:"close-btn",onClick:t[6]||(t[6]=e=>i.showHelp=!1)},"×")]),t[13]||(t[13]=(0,a.Fv)('

一些说明

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

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

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

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

1. 本人课程

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

2. 非本人课程

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

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

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

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

',1))])])):(0,a.Q3)("",!0)])}s(4979);const R={key:0,class:"modal-overlay"},q={class:"modal-content"},B={class:"course-detail"},Q={key:0,class:"share-modal"},J={key:1,class:"error-modal"},H={class:"rating-section"},K={class:"total-rating"},G={class:"progress-container"},Y={class:"stars"},Z=["onMouseover","onClick"],ee={class:"ai-summary"},te={key:0,class:"typing-cursor"},se={class:"comment-section"},oe={class:"sort-options"},ae={key:0,class:"comments-list"},ne={class:"comment-meta"},ie={class:"comment-time",style:{"margin-left":"10px"}},le=["onClick"],re={style:{"margin-top":"8px"}},ce={class:"comment-actions"},ue={style:{color:"red"}},de=["onClick"],he=["onClick"],me={key:1,class:"no-comments"},ge={key:2,class:"chat-modal-overlay"},pe={class:"chat-modal-content"},ke={class:"chat-modal-actions"},ve=["disabled"],Ce={key:3,class:"chat-modal-overlay"},be={class:"chat-modal-content"},ye={class:"chat-modal-actions"},fe={class:"new-comment"};function Le(e,t,s,n,i,l){const r=(0,a.g2)("el-progress");return s.isVisible?((0,a.uX)(),(0,a.CE)("div",R,[(0,a.Lk)("div",q,[(0,a.Lk)("span",{class:"close",onClick:t[0]||(t[0]=(...e)=>l.closeModal&&l.closeModal(...e))},"×"),(0,a.Lk)("div",B,[(0,a.Lk)("h3",null,[(0,a.eW)((0,f.v_)(s.course.course_name)+" ",1),s.course.titles&&s.course.titles.length>0?((0,a.uX)(!0),(0,a.CE)(a.FK,{key:0},(0,a.pI)(s.course.titles,(e=>((0,a.uX)(),(0,a.CE)("span",{key:e.title,class:"course-title",style:(0,f.Tr)({borderColor:e.color,color:e.color})},(0,f.v_)(e.title),5)))),128)):(0,a.Q3)("",!0),(0,a.Lk)("button",{class:"share-btn",onClick:t[1]||(t[1]=(...e)=>l.shareCourse&&l.shareCourse(...e))},"分享给好友")]),(0,a.Lk)("p",null,[t[16]||(t[16]=(0,a.Lk)("strong",null,"分类:",-1)),(0,a.eW)(" "+(0,f.v_)(l.getCategoryName(s.course.category_id)),1)]),(0,a.Lk)("p",null,[t[17]||(t[17]=(0,a.Lk)("strong",null,"教师:",-1)),(0,a.eW)(" "+(0,f.v_)(s.course.teachers),1)]),(0,a.Lk)("p",null,[t[18]||(t[18]=(0,a.Lk)("strong",null,"开课院系:",-1)),(0,a.eW)(" "+(0,f.v_)(l.getCollegeName(s.course.college)),1)]),i.showShareModal?((0,a.uX)(),(0,a.CE)("div",Q," 链接复制成功,快去分享给其他小伙伴吧! ")):(0,a.Q3)("",!0),i.showErrorModal?((0,a.uX)(),(0,a.CE)("div",J," 获取评论数据失败,正在刷新页面... ")):(0,a.Q3)("",!0),(0,a.Lk)("div",H,[(0,a.Lk)("h4",null,"课程实时平均分 ("+(0,f.v_)(s.course.rating_count)+"人评分)",1),(0,a.Lk)("div",K,(0,f.v_)(i.totalRating),1),(0,a.Lk)("div",G,[(0,a.bF)(r,{class:"progress",percentage:i.fiveStarPercent,status:"success","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("5星: "+(0,f.v_)(i.fiveStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(r,{class:"progress",percentage:i.fourStarPercent,status:"success","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("4星: "+(0,f.v_)(i.fourStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(r,{class:"progress",percentage:i.threeStarPercent,status:"warning","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("3星: "+(0,f.v_)(i.threeStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(r,{class:"progress",percentage:i.twoStarPercent,status:"warning","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("2星: "+(0,f.v_)(i.twoStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"]),(0,a.bF)(r,{class:"progress",percentage:i.oneStarPercent,status:"exception","text-inside":""},{default:(0,a.k6)((()=>[(0,a.eW)("1星: "+(0,f.v_)(i.oneStarPercent.toFixed(2))+"%",1)])),_:1},8,["percentage"])]),(0,a.Lk)("div",Y,[((0,a.uX)(),(0,a.CE)(a.FK,null,(0,a.pI)(5,(e=>(0,a.Lk)("span",{key:e,class:(0,f.C4)({highlighted:e<=i.userRating}),onMouseover:t=>l.highlightStars(e),onMouseout:t[2]||(t[2]=(...e)=>l.resetStars&&l.resetStars(...e)),onClick:t=>l.confirmRating(e)}," ★ ",42,Z))),64))])]),(0,a.Lk)("p",ee,[t[19]||(t[19]=(0,a.Lk)("span",{style:{display:"block","margin-bottom":"-15px"}},[(0,a.Lk)("strong",null,"AI课程总结"),(0,a.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,a.Lk)("span",{style:{"font-size":"12px","margin-left":"5px"}},[(0,a.eW)(" 内容由 "),(0,a.Lk)("img",{src:"https://download.东北大学.com/course_system/deepseek.svg",style:{height:"16px","vertical-align":"middle"}}),(0,a.eW)(" DeepSeek V3 生成,仅供参考 ")])],-1)),t[20]||(t[20]=(0,a.Lk)("br",null,null,-1)),i.displayedSummary?((0,a.uX)(),(0,a.CE)(a.FK,{key:0},[(0,a.eW)((0,f.v_)(i.displayedSummary),1),i.isTyping?((0,a.uX)(),(0,a.CE)("span",te,"|")):(0,a.Q3)("",!0)],64)):((0,a.uX)(),(0,a.CE)(a.FK,{key:1},[(0,a.eW)(" 当前课程的评分和评论数据过少,暂不能生成AI总结。 ")],64))])]),(0,a.Lk)("div",se,[(0,a.Lk)("div",oe,[(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"radio",value:"like_count","onUpdate:modelValue":t[3]||(t[3]=e=>i.sortBy=e),onChange:t[4]||(t[4]=(...e)=>l.fetchComments&&l.fetchComments(...e))},null,544),[[o.XL,i.sortBy]]),t[21]||(t[21]=(0,a.eW)(" 赞数最多优先"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"radio",value:"comment_time","onUpdate:modelValue":t[5]||(t[5]=e=>i.sortBy=e),onChange:t[6]||(t[6]=(...e)=>l.fetchComments&&l.fetchComments(...e))},null,544),[[o.XL,i.sortBy]]),t[22]||(t[22]=(0,a.eW)(" 最新评论优先"))])]),l.filteredComments?((0,a.uX)(),(0,a.CE)("div",ae,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.comments,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.comment_id,class:"comment"},[(0,a.Lk)("div",ne,[(0,a.Lk)("strong",null,(0,f.v_)(e.nickname),1),(0,a.Lk)("span",ie,"发表于 "+(0,f.v_)(l.formatTime(e.comment_time)),1),(0,a.Lk)("span",{class:(0,f.C4)(["like-section",{liked:e.is_liked}]),onClick:t=>l.toggleLike(e)}," ❤ "+(0,f.v_)(e.like_count),11,le)]),(0,a.Lk)("div",re,(0,f.v_)(e.comment_content),1),(0,a.Lk)("div",ce,[(0,a.Lk)("span",null,[t[23]||(t[23]=(0,a.eW)("评分: ")),(0,a.Lk)("strong",ue,(0,f.v_)(e.rating),1)]),e.deleteable?((0,a.uX)(),(0,a.CE)("button",{key:0,onClick:t=>l.deleteComment(e.comment_id),class:"delete-btn"}," 删除 ",8,de)):((0,a.uX)(),(0,a.CE)("button",{key:1,class:"chat-start-btn",onClick:t=>l.openChatModal(e.comment_id)}," 发起聊天 ",8,he))])])))),128))])):((0,a.uX)(),(0,a.CE)("p",me,"本课程暂无评论。")),i.isChatModalVisible?((0,a.uX)(),(0,a.CE)("div",ge,[(0,a.Lk)("div",pe,[(0,a.Lk)("span",{class:"chat-close-btn",onClick:t[7]||(t[7]=(...e)=>l.closeChatModal&&l.closeChatModal(...e))},"×"),t[24]||(t[24]=(0,a.Lk)("h3",null,"发起聊天",-1)),(0,a.bo)((0,a.Lk)("textarea",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.chatMessage=e),placeholder:"请输入聊天内容(至少6个字符)",class:"chat-textarea"},null,512),[[o.Jo,i.chatMessage]]),(0,a.Lk)("div",ke,[(0,a.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>l.submitChat&&l.submitChat(...e)),disabled:i.chatMessage.length<6},"发起",8,ve)])])])):(0,a.Q3)("",!0),i.isConversationExistsModalVisible?((0,a.uX)(),(0,a.CE)("div",Ce,[(0,a.Lk)("div",be,[(0,a.Lk)("span",{class:"chat-close-btn",onClick:t[10]||(t[10]=(...e)=>l.closeConversationExistsModal&&l.closeConversationExistsModal(...e))},"×"),t[25]||(t[25]=(0,a.Lk)("h3",null,"在此课程下,您与此用户已有会话!",-1)),(0,a.Lk)("div",ye,[(0,a.Lk)("button",{onClick:t[11]||(t[11]=e=>l.navigateToConversation(i.existingConversationId))},"进入会话"),(0,a.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>l.closeConversationExistsModal&&l.closeConversationExistsModal(...e))},"取消")])])])):(0,a.Q3)("",!0),(0,a.Lk)("div",fe,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[13]||(t[13]=e=>i.nickname=e),placeholder:"推荐您起个有意义的昵称,如:被x老师伤透了心"},null,512),[[o.Jo,i.nickname]]),(0,a.bo)((0,a.Lk)("textarea",{"onUpdate:modelValue":t[14]||(t[14]=e=>i.commentContent=e),placeholder:"我们推荐您分享本课程的课程内容、学习难度、考核方式和给分好坏,以帮助更多同学做出判断。支持删除自己的评论。",style:{resize:"none",height:"50px"}},null,512),[[o.Jo,i.commentContent]]),(0,a.Lk)("button",{onClick:t[15]||(t[15]=(...e)=>l.submitComment&&l.submitComment(...e))},"提交评论")])])])])):(0,a.Q3)("",!0)}var _e={props:{isVisible:{type:Boolean,required:!0},course:{type:Object,required:!0}},data(){return{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}},async mounted(){try{await Promise.all([this.fetchAndCacheEmail(),this.fetchRatingDistribution(),this.fetchUserRating()])}catch(e){console.error("Error loading data:",e)}},watch:{async course(e){if(e&&e.course_id){this.aiSummary=null,this.displayedSummary="",this.isTyping=!1;try{await Promise.all([this.fetchRatingDistribution(),this.fetchUserRating(),this.fetchComments(),this.fetchAISummary()])}catch(t){console.error("Error fetching course details:",t)}}},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:{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=this.getUserEmailFromCookie(),t=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-user-rating?user_email=${e}&course_id=${this.course.course_id}`);if(200===t.status){const e=await t.json();this.userRating=e.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=this.getUserEmailFromCookie(),s=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-rating",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:t,course_id:this.course.course_id,rating:e})});s.ok&&(this.fetchRatingDistribution(),this.fetchUserRating())},async typewriterEffect(e,t=30){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{const e=document.cookie.split("; ").find((e=>e.startsWith("token=")));if(!e)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);const t=e.split("=")[1],s=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/get-comments?course_id=${this.course.course_id}&sort_by=${this.sortBy}`,{headers:{Authorization:t}});if(403===s.status)return this.showErrorModal=!0,void setTimeout((()=>{window.location.reload()}),2e3);if(404===s.status)return void(this.comments=[]);if(!s.ok)throw new Error("获取评论失败");const o=await s.json();this.comments=o.comments}catch(e){console.error("获取评论失败:",e),this.showErrorModal=!0,setTimeout((()=>{window.location.reload()}),2e3)}},async toggleLike(e){const t=this.getUserEmailFromCookie();e.is_liked?await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/unlike-comment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:t,comment_id:e.comment_id})}):await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/like-comment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:t,comment_id:e.comment_id})}),this.fetchComments()},async submitComment(){if(this.nickname.length<3||this.commentContent.length<6)return void alert("您的昵称请至少包含3个字符,评论请至少包含6个字符。");const e=this.getUserEmailFromCookie();await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/submit-comment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({user_email:e,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(),o=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${o}-${a} ${n}:${i}`},async fetchAndCacheEmail(){if(this.cachedEmail)return;const e=document.cookie.split("; "),t=e.find((e=>e.startsWith("token="))),s=t?t.split("=")[1]:"";if(s)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:s}}),t=await e.json();e.ok&&t.email?this.cachedEmail=t.email:console.error("JWT验证失败或未找到邮箱")}catch(o){console.error("JWT验证时出错:",o)}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:document.cookie.split("; ").find((e=>e.startsWith("token="))).split("=")[1]},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=document.cookie.split("; ").find((e=>e.startsWith("token="))).split("=")[1],s=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/delete-comment",{method:"POST",headers:{"Content-Type":"application/json",Authorization:t},body:JSON.stringify({comment_id:e})});if(s.ok)this.fetchComments();else{const e=await s.json();alert(e.error||"删除评论失败")}}catch(s){console.error("删除评论出错:",s),alert("删除评论失败")}}}};const we=(0,m.A)(_e,[["render",Le],["__scopeId","data-v-c515cfa2"]]);var Ee=we,xe={components:{CourseDetailModal:Ee},data(){return{submissions:[],newCourseName:"",newCategoryId:"",newTeachers:"",newCollege:"",currentPage:1,itemsPerPage:10,totalPages:1,isLoaded:!1,selectedCourse:null,showDetail:!1,cachedEmail:null,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:"资源与土木工程学院"},showHelp:!1}},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(){setTimeout((async()=>{this.isLoaded=!0,await this.fetchAndCacheEmail(),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.decodedParam=t,this.isValid=!0,this.loadCourseDetail(this.decodedParam))}catch(t){}},methods:{isPositiveInteger(e){const t=Number(e);return Number.isInteger(t)&&t>0},async fetchAndCacheEmail(){if(this.cachedEmail)return;const e=document.cookie.split("; "),t=e.find((e=>e.startsWith("token="))),s=t?t.split("=")[1]:"";if(s)try{const e=await fetch("https://userlogin.xn--xhq44jb2fzpc.com/verifyToken",{method:"POST",headers:{"Content-Type":"application/json",Authorization:s}}),t=await e.json();e.ok&&t.email?this.cachedEmail=t.email:console.error("JWT验证失败或未找到邮箱")}catch(o){console.error("JWT验证时出错:",o)}else console.error("未找到JWT信息")},async fetchSubmissions(){const e=this.getCookie("token");if(!e)return void alert("无法获取JWT,请重新登录。");const t=await fetch("https://coursesystem.xn--xhq44jb2fzpc.com/user/user-submissions",{method:"GET",headers:{"Content-Type":"application/json",Authorization:e}}),s=await t.json();200===t.status?(this.submissions=s,this.totalPages=Math.ceil(this.submissions.length/this.itemsPerPage)):alert(s.error||"查询投稿记录失败")},getCookie(e){const t=document.cookie.split(";");for(let s of t){const[t,o]=s.trim().split("=");if(t===e)return o}return null},goToPage(e){this.currentPage=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(),o=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0"),n=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${s}-${o}-${a} ${n}:${i}`},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},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 Se=(0,m.A)(xe,[["render",O],["__scopeId","data-v-0b028aca"]]);var Pe=Se;const Te={key:0,class:"rating-page"},Me={class:"search-sort-bar"},We={class:"category-checkboxes"},je=["value"],Ie={class:"course-cards"},$e=["onClick"],Fe={class:"card-type"},Xe={class:"card-teachers"},Ue={class:"card-college"},De={class:"card-ratecount"},Ne={key:0,class:"card-topcomment"},Ae={key:1,class:"card-topcomment"},Ve={class:"card-rate"},ze={class:"pagination-bar"},Oe=["onClick"],Re=["disabled"],qe={key:1};function Be(e,t,s,n,i,l){const r=(0,a.g2)("CourseDetailModal");return i.isLoaded?((0,a.uX)(),(0,a.CE)("div",Te,[t[30]||(t[30]=(0,a.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,a.Lk)("div",Me,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"请输入课程名"},null,512),[[o.Jo,i.searchQuery]]),(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",style:{width:"450px"},placeholder:"请输入教师名,多个教师以英文逗号分隔,如“张三,李四”"},null,512),[[o.Jo,i.teacherQuery]]),(0,a.Lk)("div",We,[(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:"1"},null,512),[[o.lH,i.selectedCategories]]),t[15]||(t[15]=(0,a.eW)(" 通识选修类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[3]||(t[3]=e=>i.selectedCategories=e),value:"2"},null,512),[[o.lH,i.selectedCategories]]),t[16]||(t[16]=(0,a.eW)(" 人文选修类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCategories=e),value:"3"},null,512),[[o.lH,i.selectedCategories]]),t[17]||(t[17]=(0,a.eW)(" 专业方向类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[5]||(t[5]=e=>i.selectedCategories=e),value:"4"},null,512),[[o.lH,i.selectedCategories]]),t[18]||(t[18]=(0,a.eW)(" 体育类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[6]||(t[6]=e=>i.selectedCategories=e),value:"5"},null,512),[[o.lH,i.selectedCategories]]),t[19]||(t[19]=(0,a.eW)(" 学科基础类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[7]||(t[7]=e=>i.selectedCategories=e),value:"6"},null,512),[[o.lH,i.selectedCategories]]),t[20]||(t[20]=(0,a.eW)(" 暑期国际课"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[8]||(t[8]=e=>i.selectedCategories=e),value:"7"},null,512),[[o.lH,i.selectedCategories]]),t[21]||(t[21]=(0,a.eW)(" 数学与自然科学类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[9]||(t[9]=e=>i.selectedCategories=e),value:"8"},null,512),[[o.lH,i.selectedCategories]]),t[22]||(t[22]=(0,a.eW)(" 重修专栏"))])]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[10]||(t[10]=e=>i.sortBy=e)},t[23]||(t[23]=[(0,a.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,a.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,a.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[o.u1,i.sortBy]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[11]||(t[11]=e=>i.selectedCollege=e)},[t[24]||(t[24]=(0,a.Lk)("option",{value:""},"不限院系",-1)),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(l.filteredColleges,(([e,t])=>((0,a.uX)(),(0,a.CE)("option",{key:e,value:e},(0,f.v_)(t),9,je)))),128))],512),[[o.u1,i.selectedCollege]]),(0,a.Lk)("button",{onClick:t[12]||(t[12]=(...e)=>l.searchCourses&&l.searchCourses(...e))},"更新查询")]),(0,a.Lk)("div",Ie,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.courses,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>l.showCourseDetail(e)},[(0,a.Lk)("h3",null,[(0,a.eW)((0,f.v_)(e.course_name)+" ",1),e.titles&&e.titles.length>0?((0,a.uX)(!0),(0,a.CE)(a.FK,{key:0},(0,a.pI)(e.titles,(e=>((0,a.uX)(),(0,a.CE)("span",{key:e.title,class:"course-title",style:(0,f.Tr)({borderColor:e.color,color:e.color})},(0,f.v_)(e.title),5)))),128)):(0,a.Q3)("",!0)]),(0,a.Lk)("p",Fe,[t[25]||(t[25]=(0,a.Lk)("strong",null,"分类:",-1)),(0,a.eW)(" "+(0,f.v_)(l.getCategoryName(e.category_id)),1)]),(0,a.Lk)("p",Xe,[t[26]||(t[26]=(0,a.Lk)("strong",null,"教师:",-1)),(0,a.eW)(" "+(0,f.v_)(e.teachers),1)]),(0,a.Lk)("p",Ue,[t[27]||(t[27]=(0,a.Lk)("strong",null,"开课院系:",-1)),(0,a.eW)(" "+(0,f.v_)(l.getCollegeName(e.college)),1)]),(0,a.Lk)("p",De,[t[28]||(t[28]=(0,a.Lk)("strong",null,"评分人数:",-1)),(0,a.eW)(" "+(0,f.v_)(e.rating_count),1)]),e.top_comment?((0,a.uX)(),(0,a.CE)("p",Ne,'"'+(0,f.v_)(l.formatTopComment(e.top_comment))+'"',1)):((0,a.uX)(),(0,a.CE)("p",Ae,"暂无评论")),(0,a.Lk)("p",Ve,[(0,a.eW)((0,f.v_)(e.rating),1),t[29]||(t[29]=(0,a.Lk)("span",{class:"unit"}," 分",-1))])],8,$e)))),128))]),(0,a.Lk)("div",ze,[(0,a.Lk)("button",{onClick:t[13]||(t[13]=e=>l.goToPage(1)),class:(0,f.C4)({active:1===i.currentPage})},"首页",2),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(l.getPaginationPages(),(e=>((0,a.uX)(),(0,a.CE)("button",{key:e,onClick:t=>l.goToPage(e),class:(0,f.C4)({active:i.currentPage===e})},(0,f.v_)(e),11,Oe)))),128)),(0,a.Lk)("button",{onClick:t[14]||(t[14]=e=>l.goToPage(i.totalPages)),class:(0,f.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,Re)]),(0,a.bF)(r,{isVisible:i.showDetail,course:i.selectedCourse,onClose:l.closeCourseDetail},null,8,["isVisible","course","onClose"])])):((0,a.uX)(),(0,a.CE)("div",qe,t[31]||(t[31]=[(0,a.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var Qe={components:{CourseDetailModal:Ee},data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,showDetail:!1,selectedCourse:null,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],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(){setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},methods:{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}`:"",o=encodeURIComponent(this.searchQuery),a=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${o}&teacher=${a}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i},async fetchTotalPages(){const e=0===this.selectedCategories.length?"1,2,3,4,5,6,7,8":this.selectedCategories.join(","),t=this.selectedCollege?`&college=${this.selectedCollege}`:"",s=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),a=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses/pages?search=${s}&teacher=${o}&category=${e}${t}`),n=await a.json();this.totalPages=n.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,o=10;if(t<=o)for(let a=1;a<=t;a++)e.push(a);else{let o=Math.max(s-5,1),a=Math.min(s+4,t);s<=6&&(o=1,a=10),s>=t-4&&(o=t-9,a=t);for(let t=o;t<=a;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses(),this.fetchTotalPages()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){this.selectedCourse={...e},this.showDetail=!0},formatTopComment(e){if(!e)return"";let t=0,s="";for(let o=0;o255?1:.5;if(t+a>29)return s+"...";t+=a,s+=e[o]}return s},closeCourseDetail(){this.showDetail=!1,this.selectedCourse=null},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 Je=(0,m.A)(Qe,[["render",Be],["__scopeId","data-v-392e0a1a"]]);var He=Je;const Ke={key:0,class:"rating-page"},Ge={class:"search-sort-bar"},Ye={class:"category-checkboxes"},Ze={class:"select-container"},et=["value"],tt={class:"course-cards"},st=["onClick"],ot={class:"card-type"},at={class:"card-teachers"},nt={class:"card-college"},it={class:"card-ratecount"},lt={key:0,class:"card-topcomment"},rt={key:1,class:"card-topcomment"},ct={class:"card-rate"},ut={class:"pagination-bar"},dt=["onClick"],ht=["disabled"],mt={key:1};function gt(e,t,s,n,i,l){const r=(0,a.g2)("CourseDetailModal");return i.isLoaded?((0,a.uX)(),(0,a.CE)("div",Ke,[t[24]||(t[24]=(0,a.Lk)("h2",{class:"rating-note"},"每页最多展示12个课程,一次最多展示10个页码。点击星星进行评分,星星记录的是您的历史评分。",-1)),(0,a.Lk)("div",Ge,[(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[0]||(t[0]=e=>i.searchQuery=e),type:"text",placeholder:"请输入课程名"},null,512),[[o.Jo,i.searchQuery]]),(0,a.bo)((0,a.Lk)("input",{"onUpdate:modelValue":t[1]||(t[1]=e=>i.teacherQuery=e),type:"text",style:{width:"450px"},placeholder:"请输入教师名,多个教师以英文逗号分隔,如“张三,李四”"},null,512),[[o.Jo,i.teacherQuery]]),(0,a.Lk)("div",Ye,[(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[2]||(t[2]=e=>i.selectedCategories=e),value:"9"},null,512),[[o.lH,i.selectedCategories]]),t[12]||(t[12]=(0,a.eW)(" 数学与自然科学类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[3]||(t[3]=e=>i.selectedCategories=e),value:"10"},null,512),[[o.lH,i.selectedCategories]]),t[13]||(t[13]=(0,a.eW)(" 人文社会科学类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[4]||(t[4]=e=>i.selectedCategories=e),value:"11"},null,512),[[o.lH,i.selectedCategories]]),t[14]||(t[14]=(0,a.eW)(" 学科基础类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[5]||(t[5]=e=>i.selectedCategories=e),value:"12"},null,512),[[o.lH,i.selectedCategories]]),t[15]||(t[15]=(0,a.eW)(" 专业方向类"))]),(0,a.Lk)("label",null,[(0,a.bo)((0,a.Lk)("input",{type:"checkbox","onUpdate:modelValue":t[6]||(t[6]=e=>i.selectedCategories=e),value:"13"},null,512),[[o.lH,i.selectedCategories]]),t[16]||(t[16]=(0,a.eW)(" 实践类"))])]),(0,a.Lk)("div",Ze,[(0,a.bo)((0,a.Lk)("select",{class:"sortBySelect","onUpdate:modelValue":t[7]||(t[7]=e=>i.sortBy=e)},t[17]||(t[17]=[(0,a.Lk)("option",{value:"rating"},"评分由高到低",-1),(0,a.Lk)("option",{value:"rating-asc"},"评分由低到高",-1),(0,a.Lk)("option",{value:"rating_count"},"评分人数由多到少",-1)]),512),[[o.u1,i.sortBy]]),(0,a.bo)((0,a.Lk)("select",{"onUpdate:modelValue":t[8]||(t[8]=e=>i.selectedCollege=e)},[t[18]||(t[18]=(0,a.Lk)("option",{value:""},"不限院系",-1)),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(l.filteredColleges,(([e,t])=>((0,a.uX)(),(0,a.CE)("option",{key:e,value:e},(0,f.v_)(t),9,et)))),128))],512),[[o.u1,i.selectedCollege]])]),(0,a.Lk)("button",{onClick:t[9]||(t[9]=(...e)=>l.searchCourses&&l.searchCourses(...e))},"更新查询")]),(0,a.Lk)("div",tt,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(i.courses,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.course_id,class:"course-card",onClick:t=>l.showCourseDetail(e)},[(0,a.Lk)("h3",null,[(0,a.eW)((0,f.v_)(e.course_name)+" ",1),e.titles&&e.titles.length>0?((0,a.uX)(!0),(0,a.CE)(a.FK,{key:0},(0,a.pI)(e.titles,(e=>((0,a.uX)(),(0,a.CE)("span",{key:e.title,class:"course-title",style:(0,f.Tr)({borderColor:e.color,color:e.color})},(0,f.v_)(e.title),5)))),128)):(0,a.Q3)("",!0)]),(0,a.Lk)("p",ot,[t[19]||(t[19]=(0,a.Lk)("strong",null,"分类:",-1)),(0,a.eW)(" "+(0,f.v_)(l.getCategoryName(e.category_id)),1)]),(0,a.Lk)("p",at,[t[20]||(t[20]=(0,a.Lk)("strong",null,"教师:",-1)),(0,a.eW)(" "+(0,f.v_)(e.teachers),1)]),(0,a.Lk)("p",nt,[t[21]||(t[21]=(0,a.Lk)("strong",null,"开课院系:",-1)),(0,a.eW)(" "+(0,f.v_)(l.getCollegeName(e.college)),1)]),(0,a.Lk)("p",it,[t[22]||(t[22]=(0,a.Lk)("strong",null,"评分人数:",-1)),(0,a.eW)(" "+(0,f.v_)(e.rating_count),1)]),e.top_comment?((0,a.uX)(),(0,a.CE)("p",lt,'"'+(0,f.v_)(l.formatTopComment(e.top_comment))+'"',1)):((0,a.uX)(),(0,a.CE)("p",rt,"暂无评论")),(0,a.Lk)("p",ct,[(0,a.eW)((0,f.v_)(e.rating),1),t[23]||(t[23]=(0,a.Lk)("span",{class:"unit"}," 分",-1))])],8,st)))),128))]),(0,a.Lk)("div",ut,[(0,a.Lk)("button",{onClick:t[10]||(t[10]=e=>l.goToPage(1)),class:(0,f.C4)({active:1===i.currentPage})},"首页",2),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(l.getPaginationPages(),(e=>((0,a.uX)(),(0,a.CE)("button",{key:e,onClick:t=>l.goToPage(e),class:(0,f.C4)({active:i.currentPage===e})},(0,f.v_)(e),11,dt)))),128)),(0,a.Lk)("button",{onClick:t[11]||(t[11]=e=>l.goToPage(i.totalPages)),class:(0,f.C4)({active:i.currentPage===i.totalPages}),disabled:0===i.totalPages}," 尾页 ",10,ht)]),(0,a.bF)(r,{isVisible:i.showDetail,course:i.selectedCourse,onClose:l.closeCourseDetail},null,8,["isVisible","course","onClose"])])):((0,a.uX)(),(0,a.CE)("div",mt,t[25]||(t[25]=[(0,a.Lk)("p",{style:{color:"#666"}},"加载中,请稍后...",-1)])))}var pt={components:{CourseDetailModal:Ee},data(){return{searchQuery:"",teacherQuery:"",sortBy:"rating",sortOrder:"desc",selectedCategories:[],courses:[],currentPage:1,totalPages:1,showDetail:!1,selectedCourse:null,courseComments:[],isLoaded:!1,selectedCollege:"",allColleges:[],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(){setTimeout((()=>{this.isLoaded=!0,this.searchCourses()}),300),this.allColleges=Object.keys(this.collegeMap).map(Number)},methods:{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}`:"",o=encodeURIComponent(this.searchQuery),a=encodeURIComponent(this.teacherQuery),n=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${o}&teacher=${a}&sortBy=${e}&sort=${this.sortOrder}&category=${t}${s}&page=${this.currentPage}`),i=await n.json();this.courses=i},async fetchTotalPages(){const e=0===this.selectedCategories.length?"9,10,11,12,13":this.selectedCategories.join(","),t=this.selectedCollege?`&college=${this.selectedCollege}`:"",s=encodeURIComponent(this.searchQuery),o=encodeURIComponent(this.teacherQuery),a=await fetch(`https://coursesystem.xn--xhq44jb2fzpc.com/list/courses/pages?search=${s}&teacher=${o}&category=${e}${t}`),n=await a.json();this.totalPages=n.totalPages},getPaginationPages(){const e=[],t=this.totalPages,s=this.currentPage,o=10;if(t<=o)for(let a=1;a<=t;a++)e.push(a);else{let o=Math.max(s-5,1),a=Math.min(s+4,t);s<=6&&(o=1,a=10),s>=t-4&&(o=t-9,a=t);for(let t=o;t<=a;t++)e.push(t)}return e},searchCourses(){this.currentPage=1,this.fetchCourses(),this.fetchTotalPages()},goToPage(e){e<1||e>this.totalPages||(this.currentPage=e,this.fetchCourses())},showCourseDetail(e){this.selectedCourse={...e},this.showDetail=!0},formatTopComment(e){if(!e)return"";let t=0,s="";for(let o=0;o255?1:.5;if(t+a>29)return s+"...";t+=a,s+=e[o]}return s},closeCourseDetail(){this.showDetail=!1,this.selectedCourse=null},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 kt=(0,m.A)(pt,[["render",gt],["__scopeId","data-v-22fe0ea1"]]);var vt=kt;const Ct={class:"chat-page"},bt={class:"sidebar"},yt={class:"header"},ft={class:"status-text"},Lt={key:0,class:"no-conversations"},_t=["onClick"],wt={class:"conversation-name"},Et={key:0,class:"new-message-label"},xt={class:"conversation-updated-at"},St={class:"conversation-last-message"},Pt={class:"chat-container"},Tt={class:"conversation-info"},Mt={class:"message-bubble"},Wt={key:0},jt={class:"input-container"};function It(e,t,s,o,n,i){const l=(0,a.g2)("el-scrollbar"),r=(0,a.g2)("el-button"),c=(0,a.g2)("el-input"),u=(0,a.g2)("el-tooltip"),d=(0,a.g2)("CourseDetailModal");return(0,a.uX)(),(0,a.CE)("div",Ct,[(0,a.Lk)("div",bt,[(0,a.Lk)("h3",yt,[t[2]||(t[2]=(0,a.eW)(" 会话列表 ")),(0,a.Lk)("span",{class:(0,f.C4)(["connection-status",{connected:n.isConnected,disconnected:!n.isConnected}])},[(0,a.Lk)("span",{class:(0,f.C4)(["status-indicator",{connected:n.isConnected,disconnected:!n.isConnected}])},null,2),(0,a.Lk)("span",ft,(0,f.v_)(n.isConnected?"即时聊天已连接":"即时聊天已断开,正在重新连接..."),1)],2)]),(0,a.bF)(l,null,{default:(0,a.k6)((()=>[0===n.conversations.length?((0,a.uX)(),(0,a.CE)("div",Lt," 还没有会话,快去通过评论发起聊天吧! ")):((0,a.uX)(!0),(0,a.CE)(a.FK,{key:1},(0,a.pI)(n.conversations,(e=>((0,a.uX)(),(0,a.CE)("div",{key:e.conversation_id,class:(0,f.C4)(["conversation-item",e.conversation_id===n.activeConversation?"active":""]),onClick:t=>i.selectConversation(e.conversation_id)},[(0,a.Lk)("div",wt,[(0,a.eW)((0,f.v_)(e.course_name)+" ",1),(0,a.Lk)("span",{class:(0,f.C4)(["role-label",{owner:"owner"===e.role,member:"member"===e.role}])},(0,f.v_)("owner"===e.role?"我发起的":"我收到的"),3),e.is_read?(0,a.Q3)("",!0):((0,a.uX)(),(0,a.CE)("span",Et,"新消息"))]),(0,a.Lk)("small",xt,"更新时间: "+(0,f.v_)(i.formatDate(e.updated_at)),1),t[3]||(t[3]=(0,a.Lk)("br",null,null,-1)),(0,a.Lk)("small",St,(0,f.v_)(e.latest_sender?"我:":"对方:")+(0,f.v_)(e.content||"还没有消息哦,快去通过某条课程评论发起聊天吧!"),1)],10,_t)))),128))])),_:1})]),(0,a.Lk)("div",Pt,[(0,a.Lk)("div",Tt,[(0,a.Lk)("span",null,(0,f.v_)(null!==n.rating?"该用户对课程评分为 "+n.rating.toFixed(1):"该用户暂未对课程进行评分"),1),(0,a.bF)(r,{onClick:t[0]||(t[0]=e=>i.loadCourseDetail(n.selectedCourseId))},{default:(0,a.k6)((()=>t[4]||(t[4]=[(0,a.eW)("查看课程")]))),_:1})]),(0,a.bF)(l,{ref:"messageScrollbar",class:"message-list"},{default:(0,a.k6)((()=>[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(n.messages,((e,t)=>((0,a.uX)(),(0,a.CE)("div",{key:t,class:(0,f.C4)(["message",1===e.sender?"self":"other"])},[(0,a.Lk)("div",Mt,[(0,a.Lk)("span",null,(0,f.v_)(e.content),1),(0,a.Lk)("div",{class:(0,f.C4)(["message-info",1===e.sender?"align-right":"align-left"])},[(0,a.Lk)("small",null,(0,f.v_)(i.formatDate(e.created_at)),1),1===e.sender?((0,a.uX)(),(0,a.CE)("small",Wt,(0,f.v_)(e.is_read?"已读":"未读"),1)):(0,a.Q3)("",!0)],2)])],2)))),128))])),_:1},512),(0,a.Lk)("div",jt,[(0,a.bF)(c,{modelValue:n.newMessage,"onUpdate:modelValue":t[1]||(t[1]=e=>n.newMessage=e),type:"textarea",rows:"2",placeholder:"请输入您的消息,按Enter换行,Ctrl+Enter发送。",class:"locked-input",onKeydown:i.handleKeyDown},null,8,["modelValue","onKeydown"]),(0,a.bF)(u,{content:"Ctrl + Enter",placement:"top"},{default:(0,a.k6)((()=>[(0,a.bF)(r,{onClick:i.sendMessage,type:"primary"},{default:(0,a.k6)((()=>t[5]||(t[5]=[(0,a.eW)("发送")]))),_:1},8,["onClick"])])),_:1})])]),(0,a.bF)(d,{isVisible:n.showDetail,course:n.selectedCourse,onClose:i.closeCourseDetail},null,8,["isVisible","course","onClose"])])}var $t=s(4373),Ft={components:{CourseDetailModal:Ee},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 $t.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 $t.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 $t.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 $t.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 Xt=(0,m.A)(Ft,[["render",It],["__scopeId","data-v-0f09629d"]]);var Ut=Xt;const Dt={class:"about-container"},Nt={class:"about-page"},At={class:"version-timeline"};function Vt(e,t){const s=(0,a.g2)("el-timeline-item"),o=(0,a.g2)("el-timeline");return(0,a.uX)(),(0,a.CE)("div",Dt,[(0,a.Lk)("div",Nt,[t[6]||(t[6]=(0,a.Lk)("div",{class:"project-intro"},[(0,a.Lk)("h2",null,"关于本项目"),(0,a.Lk)("div",{class:"intro-content"},[(0,a.Lk)("p",null,"NEU小站课程评分系统是专门为东北大学学生设计的课程评价平台。本系统采用全匿名方式,学生可以匿名对课程进行评分和发表评论,帮助其他同学更好地了解课程信息。"),(0,a.Lk)("p",null,"系统支持选修课和必修课的评分,包括通识选修、人文选修、专业方向等多个类别。为了保护用户隐私,发表评论时不会显示用户在NEU小站的用户名,每次评论的昵称均由用户自行定义。"),(0,a.Lk)("p",null,"本系统仅对完成NEU小站校园认证的用户开放,确保信息的真实性和可靠性。未来本系统还计划为校内用户开放评分数据下载。")])],-1)),(0,a.Lk)("div",At,[t[5]||(t[5]=(0,a.Lk)("h2",null,"更新日志",-1)),(0,a.bF)(o,null,{default:(0,a.k6)((()=>[(0,a.bF)(s,{timestamp:"2025年2月",placement:"top"},{default:(0,a.k6)((()=>t[0]||(t[0]=[(0,a.Lk)("div",{class:"version-item"},[(0,a.Lk)("h4",null,"v1.1.4"),(0,a.Lk)("ul",null,[(0,a.Lk)("li",null,"优化页面样式和用户体验")])],-1),(0,a.Lk)("div",{class:"version-item"},[(0,a.Lk)("h4",null,"v1.1.3"),(0,a.Lk)("ul",null,[(0,a.Lk)("li",null,"新增AI课程总结功能,接入DeepSeek V3大模型")])],-1)]))),_:1}),(0,a.bF)(s,{timestamp:"2025年1月",placement:"top"},{default:(0,a.k6)((()=>t[1]||(t[1]=[(0,a.Lk)("div",{class:"version-item"},[(0,a.Lk)("h4",null,"v1.1.2"),(0,a.Lk)("ul",null,[(0,a.Lk)("li",null,"评论区支持删除自己的评论"),(0,a.Lk)("li",null,'优化了"评分由低到高"排序的逻辑,会先展示有评分(评分不为0)的课程'),(0,a.Lk)("li",null,"新增了2024-2025学年春季学期的140门通识选修课")])],-1)]))),_:1}),(0,a.bF)(s,{timestamp:"2024年11月",placement:"top"},{default:(0,a.k6)((()=>t[2]||(t[2]=[(0,a.Lk)("div",{class:"version-item"},[(0,a.Lk)("h4",null,"v1.1.0"),(0,a.Lk)("ul",null,[(0,a.Lk)("li",null,"新增在线聊天功能"),(0,a.Lk)("li",null,"支持从评论发起聊天")])],-1)]))),_:1}),(0,a.bF)(s,{timestamp:"2024年9月",placement:"top"},{default:(0,a.k6)((()=>t[3]||(t[3]=[(0,a.Lk)("div",{class:"version-item"},[(0,a.Lk)("h4",null,"v1.0.2"),(0,a.Lk)("ul",null,[(0,a.Lk)("li",null,"新增必修课评分功能"),(0,a.Lk)("li",null,"增加课程类别"),(0,a.Lk)("li",null,"更新用户验证相关接口,增强安全性"),(0,a.Lk)("li",null,"修复部分Bug")])],-1)]))),_:1}),(0,a.bF)(s,{timestamp:"2024年9月",placement:"top"},{default:(0,a.k6)((()=>t[4]||(t[4]=[(0,a.Lk)("div",{class:"version-item"},[(0,a.Lk)("h4",null,"v1.0.0"),(0,a.Lk)("ul",null,[(0,a.Lk)("li",null,"课程评分系统正式上线(测试版)")])],-1)]))),_:1})])),_:1})])])])}const zt={},Ot=(0,m.A)(zt,[["render",Vt],["__scopeId","data-v-0adf4200"]]);var Rt=Ot;const qt=[{path:"/",name:"home",meta:{title:"NEU小站课程评分系统"},component:P},{path:"/courses",name:"course-list",meta:{title:"我的课程 - NEU小站课程评分系统"},component:Pe},{path:"/rating",name:"rating",meta:{title:"选修课列表 - NEU小站课程评分系统"},component:He},{path:"/ratingforcomp",name:"ratingforcomp",meta:{title:"必修课列表 - NEU小站课程评分系统"},component:vt},{path:"/chat",name:"chat",meta:{title:"我的聊天 - NEU小站课程评分系统"},component:Ut},{path:"/about",name:"about",meta:{title:"关于 - NEU小站课程评分系统"},component:Rt}],Bt=(0,y.aE)({history:(0,y.LA)(),routes:qt});Bt.beforeEach(((e,t,s)=>{document.title=e.meta.title||"默认标题",s()}));var Qt=Bt;const Jt=(0,o.Ef)(C);Jt.use(Qt),Jt.use(b.A),Jt.mount("#app"),$t.A.defaults.baseURL="https://coursesystem.xn--xhq44jb2fzpc.com/",Jt.config.globalProperties.$axios=$t.A}},t={};function s(o){var a=t[o];if(void 0!==a)return a.exports;var n=t[o]={exports:{}};return e[o].call(n.exports,n,n.exports,s),n.exports}s.m=e,function(){var e=[];s.O=function(t,o,a,n){if(!o){var i=1/0;for(u=0;u=n)&&Object.keys(s.O).every((function(e){return s.O[e](o[r])}))?o.splice(r--,1):(l=!1,n0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[o,a,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 o in t)s.o(t,o)&&!s.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})}}(),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,o){var a,n,i=o[0],l=o[1],r=o[2],c=0;if(i.some((function(t){return 0!==e[t]}))){for(a in l)s.o(l,a)&&(s.m[a]=l[a]);if(r)var u=r(s)}for(t&&t(o);c - + - NEU小站课程评分系统 - v1.1 + NEU小站课程评分系统
diff --git a/src/App.vue b/src/App.vue index 158453b..e71ea16 100644 --- a/src/App.vue +++ b/src/App.vue @@ -151,14 +151,15 @@ html, body { width: 250px; background-color: rgb(51,51,51); padding: 10px; - height: 100vh; + height: 98%; } .main-content { flex-grow: 1; padding: 20px; background-color: white; - max-width: 920px; /* 设置最大宽度 */ + max-width: 98%; + max-height: 98%; } .forbidden-container { diff --git a/src/components/SideBar.vue b/src/components/SideBar.vue index 4514c28..f2fe4b2 100644 --- a/src/components/SideBar.vue +++ b/src/components/SideBar.vue @@ -26,12 +26,17 @@ 我的聊天 + + + 关于 + - + @@ -47,6 +52,7 @@ export default { if (routeName === 'ratingforcomp') return '3'; if (routeName === 'course-list') return '4'; if (routeName === 'chat') return '5'; + if (routeName === 'about') return '6'; return '1'; // 默认选中第一个选项卡 } }, @@ -63,8 +69,10 @@ export default { border-right: none; display: flex; flex-direction: column; - height: 95vh; /* 使侧边栏填满整个视口高度 */ + height: 98%; /* 使侧边栏填满整个视口高度 */ /* position: fixed; */ + width: 250px; + } @@ -104,10 +112,27 @@ export default { text-decoration: none; /* 确保悬停时也没有下划线 */ } +.footer-title { + font-size: 12px; /* 设置更小的字体 */ + color: #f6f0f0; /* 设置较浅的颜色 */ + text-align: center; +} + .footer-info { - margin-top: 5px; /* 增加与上一行的间距 */ - font-size: 10px; /* 设置更小的字体 */ + margin-top: 7px; /* 增加与上一行的间距 */ + font-size: 12px; /* 设置更小的字体 */ color: #beb5b5; /* 设置较浅的颜色 */ text-align: center; } + +.footer-info a { + color: #beb5b5; /* 设置较浅的颜色 */ + text-decoration: none; /* 确保悬停时也没有下划线 */ +} + +.footer-info a:hover { + color: #a8a4a6; /* 确保悬停时也没有下划线 */ +} + + \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index fcf8415..aae8ee2 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,13 +4,14 @@ import CourseList from '../views/CourseList.vue' import RatingPage from '../views/RatingPage.vue' import RatingPageforComp from '../views/RatingPageforComp.vue' import ChatList from '../views/ChatList.vue' +import AboutPage from '../views/AboutPage.vue' const routes = [ { path: '/', name: 'home', meta: { - title: 'NEU小站课程评分系统 - v1.1', + title: 'NEU小站课程评分系统', }, component: HomePage }, @@ -18,7 +19,7 @@ const routes = [ path: '/courses', name: 'course-list', meta: { - title: '我的课程 - NEU小站课程评分系统 - v1.1', + title: '我的课程 - NEU小站课程评分系统', }, component: CourseList }, @@ -26,7 +27,7 @@ const routes = [ path: '/rating', name: 'rating', meta: { - title: '选修课列表 - NEU小站课程评分系统 - v1.1', + title: '选修课列表 - NEU小站课程评分系统', }, component: RatingPage }, @@ -34,7 +35,7 @@ const routes = [ path: '/ratingforcomp', name: 'ratingforcomp', meta: { - title: '必修课列表 - NEU小站课程评分系统 - v1.1', + title: '必修课列表 - NEU小站课程评分系统', }, component: RatingPageforComp }, @@ -42,9 +43,17 @@ const routes = [ path: '/chat', name: 'chat', meta: { - title: '我的聊天 - NEU小站课程评分系统 - v1.1', + title: '我的聊天 - NEU小站课程评分系统', }, component: ChatList + }, + { + path: '/about', + name: 'about', + meta: { + title: '关于 - NEU小站课程评分系统', + }, + component: AboutPage } ] diff --git a/src/views/AboutPage.vue b/src/views/AboutPage.vue new file mode 100644 index 0000000..16fc211 --- /dev/null +++ b/src/views/AboutPage.vue @@ -0,0 +1,175 @@ + + + \ No newline at end of file diff --git a/src/views/HomePage.vue b/src/views/HomePage.vue index 14c48f3..1234f16 100644 --- a/src/views/HomePage.vue +++ b/src/views/HomePage.vue @@ -2,10 +2,6 @@

{{ greeting }}, {{ nickname }}!

-

• 2025.02.06 更新:新增AI课程总结功能,接入DeepSeek V3大模型。

-

• 2025.01.24 更新:评论区支持删除自己的评论。

- -

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

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