(function(){"use strict";var e={4707:function(e,t,s){var a=s(5130),o=s(6768);const n={key:0,class:"app-layout"},i={class:"main-content"},r={key:1,class:"forbidden-container"};function c(e,t,s,a,c,l){const u=(0,o.g2)("NavBar"),d=(0,o.g2)("router-view");return(0,o.uX)(),(0,o.CE)("div",null,[c.isAuthorized?((0,o.uX)(),(0,o.CE)("div",n,[(0,o.bF)(u),(0,o.Lk)("main",i,[(0,o.bF)(d)])])):((0,o.uX)(),(0,o.CE)("div",r,t[0]||(t[0]=[(0,o.Fv)('

您的访问被拒绝

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

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

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

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

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

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

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

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

一些说明

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

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

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

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

1. 本人课程

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

2. 非本人课程

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

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

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

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

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