detail.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>详情</title>
  7. <link rel="stylesheet" href="css/index.css">
  8. <script src="js/axios.min.js"></script>
  9. <script src="js/vue.js"></script>
  10. </head>
  11. <style>
  12. .search_left {
  13. width: 30%;
  14. }
  15. .search_left .list li {
  16. width: 100%;
  17. }
  18. .part {
  19. border-radius: 5px;
  20. }
  21. .search input {
  22. width: 100%;
  23. height: 30px;
  24. border: 1px solid #ccc;
  25. border-radius: 3px;
  26. padding: 0 10px;
  27. margin-bottom: 15px;
  28. outline: none;
  29. text-align: center;
  30. }
  31. .detail_right {
  32. width: 69%;
  33. }
  34. .tag {
  35. margin-top: 10px;
  36. /* padding-left: 20px; */
  37. }
  38. .tag span {
  39. background-color: #000;
  40. color: #fff;
  41. display: inline-block;
  42. padding: 2px 5px;
  43. margin-right: 10px;
  44. font-size: 12px;
  45. border-radius: 2px;
  46. }
  47. .tag a {
  48. color: #333;
  49. float: right;
  50. }
  51. .discuss {
  52. text-align: center;
  53. background-color: #f5f5f5;
  54. padding: 40px 20px;
  55. border: 1px solid #ccc;
  56. }
  57. .answer {
  58. padding: 20px;
  59. line-height: 26px;
  60. text-align: left;
  61. }
  62. .detail_right button {
  63. width: 150px;
  64. height: 40px;
  65. border: none;
  66. background-color: #000;
  67. color: #fff;
  68. font-weight: 600;
  69. border-radius: 3px;
  70. outline: none;
  71. }
  72. .user {
  73. margin-bottom: 10px;
  74. color: #999;
  75. font-size: 13px;
  76. }
  77. .ans {
  78. line-height: 25px;
  79. margin-bottom: 10px;
  80. color: #333;
  81. }
  82. .login_div {
  83. height: 300px;
  84. background-image: linear-gradient(90deg, #0B0B0A, #E1CAA0);
  85. text-align: center;
  86. padding-top: 140px;
  87. border-radius: 10px;
  88. }
  89. </style>
  90. <body>
  91. <section id="app">
  92. <header>
  93. <div class="left_nav">
  94. <img @click="show=!show" class="phone" width="30" src="img/menu.png" alt="">
  95. <img class="logo" src="img/logo.jpg" alt="logo">
  96. </div>
  97. <div class="nav">
  98. <a class="act" href="/index.html">猿人学面试</a>
  99. <a href="">爬虫比赛</a>
  100. <a href="">关于猿人学</a>
  101. </div>
  102. <div class="login">
  103. <div class="pc">
  104. <img width="30px" src="img/logo.jpg" alt="logo">
  105. <div v-if="userInfo" class="menu">
  106. {{userInfo.name}}
  107. <ul>
  108. <li><a href="/record.html">我的刷题记录</a></li>
  109. <li @click="logout"><a>退出登录</a></li>
  110. </ul>
  111. </div>
  112. <a v-else href="/login.html">请先登录</a>
  113. </div>
  114. <div class="phone">
  115. <span v-if="userInfo">{{userInfo.name}}</span>
  116. <a v-else href="/login.html">请先登录</a>
  117. </div>
  118. </div>
  119. </header>
  120. <transition name="slide">
  121. <div class="slide" v-if="show">
  122. <a class="act" href="/index.html">猿人学面试</a>
  123. <a href="">爬虫比赛</a>
  124. <a href="">关于猿人学</a>
  125. <a v-if="userInfo" href="/record.html">我的刷题记录</a>
  126. <a v-if="userInfo" @click="logout">退出登录</a>
  127. </div>
  128. </transition>
  129. <div class="content">
  130. <p class="navtation"><a href="/index.html">回到首页</a> - <a :href="'/list.html?cat='+param.category">
  131. <span v-if="detail.category=='crawler'">爬虫</span>
  132. <span v-else-if="detail.category=='js'">JS</span>
  133. <span v-else>安卓</span>面试题</a> - {{detail.name}}</p>
  134. <div class="left search_left">
  135. <div class="part">
  136. <p class="search">
  137. <input type="text" v-model="searchKeyword" @input="search" placeholder="题目搜索">
  138. </p>
  139. <ul class="list">
  140. <li v-for="item in list" :key="item.interviewId"><a
  141. :href="'/detail.html?cat='+param.category+'&id='+item.interviewId">{{item.name}}</a>
  142. </li>
  143. </ul>
  144. </div>
  145. <div class="part">
  146. <h2 class="sec_title"><span>贡献面试题</span></h2>
  147. <form class="form">
  148. <input v-model="name" type="text" placeholder="面试题目">
  149. <textarea v-model="content"></textarea>
  150. <button type="button" @click="post">提交</button>
  151. </form>
  152. </div>
  153. </div>
  154. <div class="right detail_right">
  155. <div class="part">
  156. <b>{{detail.name}}</b>
  157. <p class="tag">
  158. <span>{{detail.category}}</span>
  159. <a href="">分享给朋友</a>
  160. </p>
  161. </div>
  162. <div class="part">
  163. <h2 class="sec_title"><span>答题讨论</span></h2>
  164. <div class="discuss answer" v-if="userInfo">
  165. {{detail.content}}
  166. </div>
  167. <div class="discuss" v-else>
  168. <button @click="login">请登录</button>
  169. </div>
  170. </div>
  171. <div class="part">
  172. <h2 class="sec_title"><span>网友热议</span></h2>
  173. <template v-for="(item,index) in comment">
  174. <template v-if="index == 0">
  175. <p class="user">
  176. {{item.cname}} {{item.ctime}}
  177. </p>
  178. <p class="ans">
  179. {{item.content}}
  180. </p>
  181. </template>
  182. <template v-else-if="index > 0 && userInfo">
  183. <p class="user">
  184. {{item.cname}} {{item.ctime}}
  185. </p>
  186. <p class="ans">
  187. {{item.content}}
  188. </p>
  189. </template>
  190. </template>
  191. <div class="login_div" v-if="!userInfo">
  192. <button @click="login">登录后查看全部</button>
  193. </div>
  194. <div class="comment" v-if="userInfo">
  195. <textarea v-model="form.content" placeholder="留下你的想法..."></textarea>
  196. <button style="width: 100px;" @click="sendComment">提交评论</button>
  197. </div>
  198. </div>
  199. </div>
  200. </div>
  201. </section>
  202. <script src="js/public.js"></script>
  203. <script>
  204. const { createApp } = Vue;
  205. createApp({
  206. data() {
  207. return {
  208. name: '',
  209. content: '',
  210. userInfo: {},
  211. id: '',
  212. detail: {},
  213. comment: [],
  214. form: {
  215. content: '',
  216. interviewName: '',
  217. interviewId: ''
  218. },
  219. searchKeyword: '', // 添加 searchKeyword 变量
  220. list: [], // 添加 list 变量用于存储题目列表
  221. show: 0, // 添加 show 变量,
  222. param: {
  223. page: 1,
  224. page_size: 10
  225. }
  226. }
  227. },
  228. created() {
  229. this.id = new URLSearchParams(window.location.search).get('id') || '';
  230. this.param.category = new URLSearchParams(window.location.search).get('cat') || 'js';
  231. // 获取本地存储的用户ID并赋值给cid
  232. const userInfo = JSON.parse(localStorage.getItem('userInfo'));
  233. this.userInfo = userInfo;
  234. this.getData();
  235. this.getComment();
  236. },
  237. methods: {
  238. login() {
  239. window.location.href = '/login.html';
  240. },
  241. getData() {
  242. // 列表
  243. axios.get(url + '/api/yrx/que/info?interviewId=' + this.id).then(res => {
  244. if (res.data.code === 0) {
  245. this.detail = res.data.data;
  246. this.form.interviewId = this.detail.interviewId;
  247. this.form.interviewName = this.detail.name;
  248. }
  249. });
  250. // 获取题目列表
  251. axios.get(url + '/api/yrx/que/list', { params: this.param }).then(res => {
  252. if (res.data.code === 0) {
  253. this.list = res.data.data.list;
  254. }
  255. });
  256. },
  257. getComment() {
  258. axios.get(url + '/api/yrx/que/comments/list?interviewId=' + this.id).then(res => {
  259. if (res.data.code === 0) {
  260. this.comment = res.data.data.list;
  261. }
  262. });
  263. },
  264. sendComment() {
  265. if (!this.form.content) {
  266. alert('评论内容不能为空');
  267. return;
  268. }
  269. const token = localStorage.getItem('token'); // 获取token
  270. axios.post(url + '/api/yrx/que/comments', this.form, {
  271. headers: {
  272. 'Authorization': `${token}` // 添加token到header
  273. }
  274. })
  275. .then(res => {
  276. if (res.data.code === 0) {
  277. alert('评论成功');
  278. this.form.content = '';
  279. this.getComment();
  280. }
  281. })
  282. .catch(err => {
  283. alert('评论失败,请重试');
  284. console.error(err);
  285. });
  286. },
  287. post() { // 添加post方法
  288. const token = localStorage.getItem('token'); // 获取token
  289. if (!token) {
  290. window.location.href = "/login.html";
  291. return;
  292. }
  293. if (!this.name || !this.content) {
  294. alert('面试题目和内容不能为空');
  295. return;
  296. }
  297. axios.post(url + '/api/yrx/que/user/post', { name: this.name, content: this.content }, {
  298. headers: {
  299. 'Authorization': `${token}` // 添加token到header
  300. }
  301. })
  302. .then(res => {
  303. if (res.data.code === 0) {
  304. alert('提交成功');
  305. this.name = '';
  306. this.content = '';
  307. }
  308. })
  309. .catch(err => {
  310. alert('提交失败,请重试');
  311. console.error(err);
  312. });
  313. },
  314. search() { // 添加 search 方法
  315. axios.get(url + '/api/yrx/que/list', {
  316. params: {
  317. name: this.searchKeyword,
  318. category: this.detail.category,
  319. page: 1,
  320. page_size: 1000
  321. }
  322. })
  323. .then(res => {
  324. if (res.data.code === 0) {
  325. this.list = res.data.data.list;
  326. }
  327. })
  328. },
  329. logout() { // 添加 logout 方法
  330. localStorage.removeItem('userInfo');
  331. localStorage.removeItem('token');
  332. this.userInfo = null;
  333. }
  334. }
  335. }).mount('#app');
  336. </script>
  337. </body>
  338. </html>