detail.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  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: calc(25% - 20px);
  14. }
  15. .search_left .list li {
  16. width: 100%;
  17. line-height: 30px;
  18. }
  19. .part {
  20. border-radius: 5px;
  21. }
  22. .search input {
  23. width: 200px;
  24. height: 32px;
  25. border: 1px solid #ccc;
  26. border-radius: 3px;
  27. padding: 0 10px;
  28. margin-bottom: 15px;
  29. outline: none;
  30. text-align: center;
  31. }
  32. .search{
  33. position: relative;
  34. width: 200px;
  35. margin: 0 auto;
  36. }
  37. .search img{
  38. position: absolute;
  39. right: 5px;
  40. top: 5px;
  41. cursor: pointer;
  42. }
  43. .detail_right {
  44. width: 75%;
  45. }
  46. .tag {
  47. margin-top: 10px;
  48. /* padding-left: 20px; */
  49. }
  50. .tag span {
  51. background-color: #A9ABAD20;
  52. color: #666;
  53. display: inline-block;
  54. width: 60px;
  55. line-height: 25px;
  56. margin-right: 10px;
  57. font-size: 14px;
  58. border-radius: 10px;
  59. text-align: center;
  60. }
  61. .tag a {
  62. color: #333;
  63. float: right;
  64. cursor: pointer;
  65. }
  66. .discuss {
  67. text-align: center;
  68. /* background-color: #f5f5f5; */
  69. padding: 40px 20px;
  70. /* border: 1px solid #ccc; */
  71. }
  72. .discuss button{
  73. background-color: #2268D0 !important;
  74. border-radius: 20px !important;
  75. width: 200px !important;
  76. }
  77. .answer {
  78. padding: 20px;
  79. line-height: 26px;
  80. text-align: left;
  81. }
  82. .detail_right button {
  83. width: 150px;
  84. height: 40px;
  85. border: none;
  86. background-color: #000;
  87. color: #fff;
  88. font-weight: 600;
  89. border-radius: 3px;
  90. outline: none;
  91. }
  92. .user {
  93. margin-bottom: 10px;
  94. color: #999;
  95. font-size: 13px;
  96. }
  97. .ans {
  98. line-height: 25px;
  99. margin-bottom: 10px;
  100. color: #333;
  101. }
  102. .login_div {
  103. /* background-image: linear-gradient(90deg, #0B0B0A, #E1CAA0); */
  104. text-align: center;
  105. padding: 20px;
  106. border-radius: 10px;
  107. box-shadow: 0px 0px 4px 0 rgba(0,0,0,.1);
  108. margin-bottom: 15px;
  109. }
  110. .login_div button{
  111. width: 300px;
  112. background-color: #E8E8E8;
  113. color: #000;
  114. font-weight: 500;
  115. }
  116. .login_div button span{
  117. color: #0065D7;
  118. font-weight: 600;
  119. }
  120. #list li{
  121. line-height: 30px;
  122. padding: 10px 0;
  123. font-size: 14px;
  124. border-bottom: 1px solid #BBBBBB20;
  125. }
  126. #list li a{
  127. color: #0065D7;
  128. display: flex;
  129. }
  130. .part{
  131. padding: 25px;
  132. }
  133. .sec_title{
  134. color: #0065D7;
  135. border-bottom: 1px solid #f5f5f5;
  136. }
  137. .sec_title span{
  138. border-bottom: 3px solid #0065D7;
  139. line-height: 30px;
  140. }
  141. .avatar{
  142. width: 44px;
  143. height: 40px;
  144. border-radius: 50%;
  145. background-color: greenyellow;
  146. margin-right: 15px;
  147. line-height: 40px;
  148. text-align: center;
  149. font-weight: 600;
  150. font-size: 13px;
  151. }
  152. </style>
  153. <body>
  154. <section id="app">
  155. <div style="background-color: #FDC606;box-shadow: 0px 0px 4px 0 rgba(0,0,0,.5);">
  156. <header>
  157. <div class="left_nav">
  158. <img @click="show=!show" class="phone" width="30" src="img/menu.png" alt="">
  159. <a href="/index.html"><img class="logo" src="img/logo.png" alt="logo"></a>
  160. </div>
  161. <div class="nav">
  162. <a class="act" href="/index.html">主页</a>
  163. <a href="https://match.yuanrenxue.cn/" target="_blank">爬虫逆向比赛</a>
  164. <a href="https://match.yuanrenxue.cn/" target="_blank">采集进阶课程</a>
  165. <a href="https://tool.yuanrenxue.cn/" target="_blank">采集分析工具</a>
  166. <a href="https://appmatch.yuanrenxue.cn/" target="_blank">APP题目</a>
  167. <a href="https://www.yuanrenxue.cn/" target="_blank">关于猿人学</a>
  168. </div>
  169. <div class="login">
  170. <div class="pc">
  171. <!-- <img width="30px" src="img/logo.jpg" alt="logo"> -->
  172. <div v-if="userInfo" class="menu">
  173. <span class="user_avatar">{{userInfo.name[0]}}</span>
  174. {{userInfo.name}}
  175. <ul>
  176. <li><a href="/record.html">我的刷题记录</a></li>
  177. <li @click="logout"><a>退出登录</a></li>
  178. </ul>
  179. </div>
  180. <a v-else href="/login.html">请先登录</a>
  181. </div>
  182. <div class="phone">
  183. <span v-if="userInfo">{{userInfo.name}}</span>
  184. <a v-else href="/login.html">请先登录</a>
  185. </div>
  186. </div>
  187. </header>
  188. </div>
  189. <transition name="slide">
  190. <div class="slide" v-if="show">
  191. <a class="act" href="/index.html">主页</a>
  192. <a href="https://match.yuanrenxue.cn/" target="_blank">爬虫逆向比赛</a>
  193. <a href="https://match.yuanrenxue.cn/" target="_blank">采集进阶课程</a>
  194. <a href="https://tool.yuanrenxue.cn/" target="_blank">采集分析工具</a>
  195. <a href="https://appmatch.yuanrenxue.cn/" target="_blank">APP题目</a>
  196. <a href="https://www.yuanrenxue.cn/" target="_blank">关于猿人学</a>
  197. <a v-if="userInfo" href="/record.html">我的刷题记录</a>
  198. <a v-if="userInfo" @click="logout">退出登录</a>
  199. </div>
  200. </transition>
  201. <div class="content">
  202. <p class="navtation"><a href="/index.html">回到首页</a> - <a :href="'/list.html?cat='+param.category">
  203. <span v-if="detail.category=='crawler'">爬虫</span>
  204. <span v-else-if="detail.category=='js'">JS</span>
  205. <span v-else>安卓</span>面试题</a> - {{detail.name}}</p>
  206. <div class="left search_left pc">
  207. <div class="part">
  208. <p class="search">
  209. <img @click="search" width="20" src="img/search.png" alt="">
  210. <input type="text" v-model="searchKeyword" @input="search" placeholder="题目搜索">
  211. </p>
  212. <ol class="list" id="list">
  213. <li v-for="(item,i) in list" :key="item.interviewId" v-show="i<10">
  214. <a
  215. :href="'/detail.html?cat='+param.category+'&id='+item.interviewId">
  216. <span>{{i+1}}、</span>{{item.name}}</a>
  217. </li>
  218. </ol>
  219. </div>
  220. <div class="part">
  221. <h2 class="sec_title"><span>贡献面试题</span></h2>
  222. <form class="form">
  223. <input v-model="name" type="text" placeholder="面试题目">
  224. <textarea v-model="content"></textarea>
  225. <button type="button" @click="post">提交</button>
  226. </form>
  227. </div>
  228. </div>
  229. <div class="right detail_right">
  230. <div class="part">
  231. <b style="font-size: 28px;color: #000;">{{detail.name}}</b>
  232. <p class="tag">
  233. <span>{{detail.category}}</span>
  234. <a @click="copy"><img style="position: relative;top: 5px;" width="20" src="img/share.png" alt=""> 分享给朋友</a>
  235. </p>
  236. </div>
  237. <div class="part">
  238. <h2 class="sec_title"><span>优秀回答</span></h2>
  239. <div class="discuss answer" v-if="userInfo">
  240. {{detail.content}}
  241. </div>
  242. <div class="discuss" v-else>
  243. <button @click="login">点击登录查看完整内容</button>
  244. </div>
  245. </div>
  246. <div class="part">
  247. <h2 class="sec_title"><span>讨论回答</span></h2>
  248. <div style="display: flex;">
  249. <span class="avatar" :style="{background:'#d9d9d9'}">
  250. {{userInfo?userInfo.name[0]:''}}
  251. </span>
  252. <div class="login_div" v-if="!userInfo" style="width: 90%;">
  253. <button @click="login">你需要<span>注册/登录</span>才可以分享内容哦</button>
  254. </div>
  255. <div class="comment" v-else style="width: 90%;margin-bottom: 15px;">
  256. <textarea v-model="form.content" placeholder="留下你的想法..."></textarea>
  257. <button style="width: 100px;" @click="sendComment">提交评论</button>
  258. </div>
  259. </div>
  260. <template v-for="(item,index) in comment">
  261. <template v-if="index == 0">
  262. <div style="display: flex;">
  263. <span class="avatar" :style="{background:getColor()}">{{item.cname[0]}}</span>
  264. <div>
  265. <p class="user">
  266. <b style="color: #000;">{{item.cname}}</b>
  267. </p>
  268. <p class="ans">
  269. {{item.content}}
  270. </p>
  271. <p class="user">
  272. {{item.ctime}}
  273. </p>
  274. </div>
  275. </div>
  276. </template>
  277. <template v-else-if="index > 0 && userInfo">
  278. <div style="display: flex;">
  279. <span class="avatar" :style="{background:getColor()}">{{item.cname[0]}}</span>
  280. <div>
  281. <p class="user">
  282. <b style="color: #000;">{{item.cname}}</b>
  283. </p>
  284. <p class="ans">
  285. {{item.content}}
  286. </p>
  287. <p class="user">
  288. {{item.ctime}}
  289. </p>
  290. </div>
  291. </div>
  292. </template>
  293. </template>
  294. </div>
  295. </div>
  296. <div class="left search_left phone">
  297. <div class="part">
  298. <p class="search">
  299. <img @click="search" width="20" src="img/search.png" alt="">
  300. <input type="text" v-model="searchKeyword" @input="search" placeholder="题目搜索">
  301. </p>
  302. <ol class="list" id="list">
  303. <li v-for="(item,i) in list" :key="item.interviewId" v-show="i<10">
  304. <a
  305. :href="'/detail.html?cat='+param.category+'&id='+item.interviewId">
  306. <span>{{i+1}}、</span>{{item.name}}</a>
  307. </li>
  308. </ol>
  309. </div>
  310. <div class="part">
  311. <h2 class="sec_title"><span>贡献面试题</span></h2>
  312. <form class="form">
  313. <input v-model="name" type="text" placeholder="面试题目">
  314. <textarea v-model="content"></textarea>
  315. <button type="button" @click="post">提交</button>
  316. </form>
  317. </div>
  318. </div>
  319. </div>
  320. <footer>
  321. <ul>
  322. <li>
  323. <b>爬虫比赛</b> <br>
  324. <a href="https://appmatch.yuanrenxue.cn/" target="_blank">APP题目</a>
  325. <a href="https://match.yuanrenxue.cn/" target="_blank">爬虫逆向比赛</a>
  326. <a href="https://tool.yuanrenxue.cn/" target="_blank">采集分析工具</a>
  327. </li>
  328. <li>
  329. <b>爬虫课程</b> <br>
  330. <a href="https://shop45147253.m.youzan.com/wscgoods/detail/2okabph85ypv1?banner_id=f.86209928~goods.2~1~rVebiaQ5&alg_id=0&slg=0&components_style_layout=0&reft=1744878857227&spm=f.86209928&sf=wx_sm" target="_blank">爬虫逆向进阶课</a>
  331. <a href="https://shop45147253.m.youzan.com/wscgoods/detail/2xli2kj7ku3a5zk?banner_id=f.86209928~goods.2~2~lWrtebiJ&alg_id=0&slg=0&components_style_layout=0&reft=1744878880491&spm=f.86209928&sf=wx_sm" target="_blank">反爬&风控对抗课</a>
  332. <a href="https://shop45147253.m.youzan.com/wscgoods/detail/361rmliyhfwr184?banner_id=f.86209928~goods.2~3~25r4gDL2&alg_id=0&slg=0&components_style_layout=0&reft=1744878921640&spm=f.86209928&sf=wx_sm" target="_blank">0基础+爬虫逆向课</a>
  333. </li>
  334. <li>
  335. <b>关于猿人学</b> <br>
  336. <a href="https://www.yuanrenxue.cn/tricks" target="_blank">Python技术杂谈</a>
  337. <a href="https://www.yuanrenxue.cn/earn-money" target="_blank">Python爬虫挣钱</a>
  338. </li>
  339. <li class="contact" style="display: flex;line-height: 30px;">
  340. <img style="margin-right: 10px;" width="100" height="100" src="img/wx.jpg" alt="">
  341. 扫一扫加我微信 <br>
  342. 备注面试题 <br>
  343. 拉你进面试交流群
  344. </li>
  345. </ul>
  346. <p>成都老猿智能科技有限公司Copyright @ 2025 猿人学面试 蜀ICP备2022000052号-2</p>
  347. </footer>
  348. </section>
  349. <script src="js/public.js"></script>
  350. <script>
  351. const { createApp } = Vue;
  352. createApp({
  353. data() {
  354. return {
  355. name: '',
  356. content: '',
  357. userInfo: {},
  358. id: '',
  359. detail: {},
  360. comment: [],
  361. form: {
  362. content: '',
  363. interviewName: '',
  364. interviewId: ''
  365. },
  366. searchKeyword: '', // 添加 searchKeyword 变量
  367. list: [], // 添加 list 变量用于存储题目列表
  368. show: 0, // 添加 show 变量,
  369. param: {
  370. page: 1,
  371. page_size: 10
  372. }
  373. }
  374. },
  375. created() {
  376. this.id = new URLSearchParams(window.location.search).get('id') || '';
  377. this.param.category = new URLSearchParams(window.location.search).get('cat') || 'js';
  378. // 获取本地存储的用户ID并赋值给cid
  379. const userInfo = JSON.parse(localStorage.getItem('userInfo'));
  380. this.userInfo = userInfo;
  381. this.getData();
  382. this.getComment();
  383. },
  384. methods: {
  385. login() {
  386. window.location.href = '/login.html';
  387. },
  388. getColor() {
  389. // 生成随机饱和度低的颜色
  390. const r = Math.floor(Math.random() * 128)+120; // 随机生成 0-127 的红色值
  391. const g = Math.floor(Math.random() * 128)+120; // 随机生成 0-127 的绿色值
  392. const b = Math.floor(Math.random() * 128)+120; // 随机生成 0-127 的蓝色值
  393. return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
  394. },
  395. getData() {
  396. // 列表
  397. axios.get(url + '/api/yrx/que/info?interviewId=' + this.id).then(res => {
  398. if (res.data.code === 0) {
  399. this.detail = res.data.data;
  400. this.form.interviewId = this.detail.interviewId;
  401. this.form.interviewName = this.detail.name;
  402. }
  403. });
  404. // 获取题目列表
  405. axios.get(url + '/api/yrx/que/list', { params: this.param }).then(res => {
  406. if (res.data.code === 0) {
  407. this.list = res.data.data.list;
  408. }
  409. });
  410. },
  411. getComment() {
  412. axios.get(url + '/api/yrx/que/comments/list?interviewId=' + this.id).then(res => {
  413. if (res.data.code === 0) {
  414. this.comment = res.data.data.list;
  415. }
  416. });
  417. },
  418. sendComment() {
  419. if (!this.form.content) {
  420. alert('评论内容不能为空');
  421. return;
  422. }
  423. const token = localStorage.getItem('token'); // 获取token
  424. axios.post(url + '/api/yrx/que/comments', this.form, {
  425. headers: {
  426. 'Authorization': `${token}` // 添加token到header
  427. }
  428. })
  429. .then(res => {
  430. if (res.data.code === 0) {
  431. alert('评论成功');
  432. this.form.content = '';
  433. this.getComment();
  434. }
  435. })
  436. .catch(err => {
  437. alert('评论失败,请重试');
  438. console.error(err);
  439. });
  440. },
  441. post() { // 添加post方法
  442. const token = localStorage.getItem('token'); // 获取token
  443. if (!token) {
  444. window.location.href = "/login.html";
  445. return;
  446. }
  447. if (!this.name || !this.content) {
  448. alert('面试题目和内容不能为空');
  449. return;
  450. }
  451. axios.post(url + '/api/yrx/que/user/post', { name: this.name, content: this.content }, {
  452. headers: {
  453. 'Authorization': `${token}` // 添加token到header
  454. }
  455. })
  456. .then(res => {
  457. if (res.data.code === 0) {
  458. alert('提交成功');
  459. this.name = '';
  460. this.content = '';
  461. }
  462. })
  463. .catch(err => {
  464. alert('提交失败,请重试');
  465. console.error(err);
  466. });
  467. },
  468. search() { // 添加 search 方法
  469. axios.get(url + '/api/yrx/que/list', {
  470. params: {
  471. name: this.searchKeyword,
  472. category: this.detail.category,
  473. page: 1,
  474. page_size: 1000
  475. }
  476. })
  477. .then(res => {
  478. if (res.data.code === 0) {
  479. this.list = res.data.data.list;
  480. }
  481. })
  482. },
  483. logout() { // 添加 logout 方法
  484. localStorage.removeItem('userInfo');
  485. localStorage.removeItem('token');
  486. this.userInfo = null;
  487. },
  488. copy(){
  489. const text = window.location.href;
  490. navigator.clipboard.writeText(text)
  491. .then(() => {
  492. alert('链接已复制,求分享给好友吧!');
  493. })
  494. .catch((error) => {
  495. alert('复制失败,请重试。');
  496. console.error('复制失败:', error);
  497. });
  498. }
  499. }
  500. }).mount('#app');
  501. </script>
  502. </body>
  503. </html>