searchDetail.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. <template>
  2. <div class="search-detail" v-loading="loading">
  3. <Header
  4. :headerBg="'#299772'"
  5. :headerBorder="'#30A47D'"
  6. :userBg="'rgba(0, 0, 0, 0.08)'"
  7. :LoginNavIndex="-1"
  8. />
  9. <div class="banner">
  10. <a class="goback" @click="$router.go(-1)"
  11. ><i class="el-icon-arrow-left"></i>返回</a
  12. >
  13. <div class="banner-inner">
  14. <img src="../../assets/icon-search-small.png" />
  15. <SearchInput
  16. class="search-compent"
  17. :searchQuery="searchQuery"
  18. :selectIndex="selectIndex"
  19. @changeSelectIndex="changeSelectIndex"
  20. />
  21. </div>
  22. </div>
  23. <div class="main">
  24. <!-- <ul class="typelist">
  25. <li class="typeitem" :class="[typeIndex===indexT?'active':'']" v-for="(itemT,indexT) in typeList" :key="indexT" @click="handleTypeIndex('typeIndex',indexT)">
  26. <svg-icon :icon-class="itemT.img" className="icon-img"></svg-icon>
  27. <span class="OPPOSans">{{itemT.name}}</span>
  28. <b class="OPPOSans">{{itemT.value}}</b>
  29. </li>
  30. </ul> -->
  31. <div class="main-inner">
  32. <!-- <ul v-if="typeList && typeList.length > 0" class="gradelist">
  33. <li
  34. :class="['gradeitem', indeG === typeIndex ? 'active' : '']"
  35. v-for="(itemG, indeG) in typeList"
  36. :key="indeG"
  37. @click="handleTypeIndex('typeIndex', indeG)"
  38. >
  39. {{ itemG.name + " " + itemG.value }}
  40. </li>
  41. </ul> -->
  42. <ul v-if="gradeList && gradeList.length > 0" class="gradelist">
  43. <li
  44. :class="[
  45. 'gradeitem',
  46. itemG.study_phase === gradeIndex ? 'active' : '',
  47. ]"
  48. v-for="(itemG, indeG) in gradeList"
  49. :key="indeG"
  50. @click="handleTypeIndex('gradeIndex', itemG.study_phase)"
  51. >
  52. {{ itemG.study_phase_name }}
  53. </li>
  54. </ul>
  55. <ul v-if="yearList && yearList.length > 0" class="gradelist">
  56. <li
  57. :class="['gradeitem', itemG.value === yearIndex ? 'active' : '']"
  58. v-for="(itemG, indeG) in yearList"
  59. :key="indeG"
  60. @click="handleTypeIndex('yearIndex', itemG.value)"
  61. >
  62. {{ itemG.label }}
  63. </li>
  64. </ul>
  65. <p class="timeconsume">
  66. {{ courseTotal }}条结果,耗时
  67. {{ takeTime >= 1000 ? takeTime / 1000 + "s" : takeTime + "ms" }}。
  68. </p>
  69. <div class="searchChangebox">
  70. <div
  71. class="searchChange"
  72. :class="[item.sortName == sortField ? 'active' : '']"
  73. v-for="(item, indexC) in changeList"
  74. :key="indexC"
  75. >
  76. <span>
  77. {{ item.name }}
  78. </span>
  79. <div :class="['sort']">
  80. <div>
  81. <svg-icon
  82. icon-class="up"
  83. className="icon-up"
  84. :class="[item.sort == 'up' ? 'active' : '']"
  85. @click="SortEvent('up', item.name, item.sortName)"
  86. ></svg-icon>
  87. </div>
  88. <div>
  89. <svg-icon
  90. icon-class="down"
  91. className="icon-down"
  92. :class="[item.sort == 'down' ? 'active' : '']"
  93. @click="SortEvent('down', item.name, item.sortName)"
  94. ></svg-icon>
  95. </div>
  96. </div>
  97. </div>
  98. </div>
  99. <template v-if="searchList && searchList.length > 0">
  100. <div
  101. class="search-item"
  102. v-for="(itemS, indexS) in searchList"
  103. :key="indexS"
  104. @click="handleLink(itemS)"
  105. >
  106. <el-image :src="itemS.src" :fit="'cover'"> </el-image>
  107. <div class="search-inner">
  108. <div class="top">
  109. <h2 v-html="itemS.title"></h2>
  110. <span v-html="itemS.author"></span>
  111. </div>
  112. <div class="content" v-html="itemS.content"></div>
  113. <div class="bottom">
  114. <span v-if="itemS.iss_no">{{ itemS.iss_no }}</span>
  115. <span v-if="itemS.study_phase_name">{{
  116. itemS.study_phase_name
  117. }}</span>
  118. <span v-if="itemS.wc">长度:{{ itemS.wc }}</span>
  119. <span v-if="itemS.wdc">词数:{{ itemS.wdc }}</span>
  120. </div>
  121. </div>
  122. </div>
  123. <el-pagination
  124. background
  125. :current-page="currentPage"
  126. :page-size="page_capacity"
  127. :page-sizes="[10, 20, 30, 40, 50]"
  128. :total="courseTotal"
  129. layout="sizes, prev, pager, next, jumper"
  130. @current-change="handleCurrentChange"
  131. @size-change="handleSizeChange"
  132. />
  133. </template>
  134. <div class="nodata" v-else>
  135. <img src="../../assets/nodata.png" />
  136. <p>找不到文件</p>
  137. </div>
  138. </div>
  139. </div>
  140. </div>
  141. </template>
  142. <script>
  143. //这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  144. //例如:import 《组件名称》from ‘《组件路径》';
  145. import Header from "../../components/Header.vue";
  146. import SearchInput from "./components/SearchInput.vue";
  147. import BookCard from "@/components/common/BookCard.vue";
  148. import { getLogin } from "@/api/ajax";
  149. export default {
  150. //import引入的组件需要注入到对象中才能使用
  151. components: { Header, SearchInput, BookCard },
  152. props: {},
  153. data() {
  154. //这里存放数据
  155. return {
  156. searchQuery: this.$route.query.content ? this.$route.query.content : "",
  157. config: this.$route.query.headerConfig
  158. ? decodeURIComponent(this.$route.query.headerConfig)
  159. : "",
  160. LoginNavIndex: 0,
  161. userBg: "rgba(0, 0, 0, 0.24)",
  162. headerBorder: "#5C5C5C",
  163. headerBg: "#1F1F1F",
  164. selectIndex: this.$route.query.selectIndex
  165. ? this.$route.query.selectIndex * 1
  166. : 0,
  167. typeIndex: 0,
  168. gradeList: [],
  169. yearList: [
  170. {
  171. label: "全部",
  172. value: null,
  173. },
  174. ],
  175. gradeIndex: null,
  176. yearIndex: null,
  177. sortType: 0,
  178. sortField: "",
  179. changeList: [
  180. {
  181. name: "长度",
  182. sort: "",
  183. sortName: "wc",
  184. },
  185. {
  186. name: "词数",
  187. sort: "",
  188. sortName: "wdc",
  189. },
  190. ],
  191. searchList: [],
  192. currentPage: 1, // 当前页码
  193. page_capacity: 10, // 每页条数
  194. courseTotal: 0, // 数据总条数
  195. timer: null,
  196. takeTime: 0, //耗时
  197. loading: false,
  198. };
  199. },
  200. //计算属性 类似于data概念
  201. computed: {},
  202. //监控data中数据变化
  203. watch: {
  204. searchQuery: {
  205. handler(val, oldVal) {
  206. if (val !== oldVal) {
  207. this.currentPage = 1;
  208. this.searchArticle();
  209. }
  210. },
  211. // 深度观察监听
  212. deep: true,
  213. },
  214. },
  215. //方法集合
  216. methods: {
  217. handleTypeIndex(type, index) {
  218. this[type] = index;
  219. this.currentPage = 1;
  220. this.searchArticle();
  221. },
  222. SortEvent(type, name, sortName) {
  223. let sort = "";
  224. this.changeList.forEach((item) => {
  225. if (item.name == name) {
  226. item.sort = type;
  227. sort = type;
  228. } else {
  229. item.sort = "";
  230. }
  231. });
  232. if (sort == "down") {
  233. this.sortType = 1;
  234. } else {
  235. this.sortType = 0;
  236. }
  237. this.sortField = sortName;
  238. this.currentPage = 1;
  239. this.searchArticle();
  240. },
  241. // 跳转文章
  242. handleLink(item) {
  243. let url = this.config + "&&&搜索";
  244. this.$router.push({
  245. path: "/articleDetail",
  246. query: {
  247. headerConfig: encodeURIComponent(url),
  248. iss_id: item.iss_id,
  249. id: item.art_id,
  250. },
  251. });
  252. },
  253. // 切换每页条数
  254. handleSizeChange(val) {
  255. this.currentPage = 1;
  256. this.page_capacity = val;
  257. this.searchArticle();
  258. },
  259. // 切换页码
  260. handleCurrentChange(val) {
  261. this.currentPage = val;
  262. this.searchArticle();
  263. },
  264. // 学段列表
  265. getStudyList() {
  266. let MethodName = "/OrgServer/DictManager/GetStudyPhaseList";
  267. getLogin(MethodName, {})
  268. .then((res) => {
  269. if (res.status === 1) {
  270. let gradeList = [
  271. {
  272. study_phase: null,
  273. study_phase_name: "全部",
  274. },
  275. ];
  276. this.gradeList = gradeList.concat(res.study_phase_list);
  277. }
  278. })
  279. .catch(() => {});
  280. },
  281. // 获取年份列表
  282. getYearList() {
  283. this.yearList = [
  284. {
  285. value: null,
  286. label: "全部",
  287. },
  288. ];
  289. let yearList = [];
  290. let MethodName = "/ShopServer/Client/ShopHomeQuery/GetIssueYearLabelList";
  291. getLogin(MethodName, {
  292. goods_type: 2,
  293. })
  294. .then((res) => {
  295. if (res.status === 1) {
  296. res.year_label_list.forEach((nowYear) => {
  297. let obj = {
  298. value: nowYear,
  299. label: nowYear,
  300. };
  301. yearList.push(obj);
  302. });
  303. this.yearList = this.yearList.concat(yearList);
  304. }
  305. })
  306. .catch(() => {});
  307. },
  308. // 查询搜索内容
  309. searchArticle() {
  310. this.loading = true;
  311. this.takeTime = 0;
  312. this.timer = setInterval(() => {
  313. this.takeTime += 20;
  314. }, 20);
  315. let orderObj = null;
  316. if (this.sortField) {
  317. orderObj = {
  318. name: this.sortField,
  319. asc: !this.sortType,
  320. };
  321. }
  322. let MethodName = "/PaperServer/Client/Search/SearchArticle";
  323. let data = {
  324. word: this.searchQuery,
  325. page_size: this.page_capacity,
  326. page_no: this.currentPage,
  327. only_my_bought: this.selectIndex,
  328. study_phase: this.gradeIndex,
  329. release_year: this.yearIndex,
  330. order_bys: orderObj ? [orderObj] : [],
  331. };
  332. getLogin(MethodName, data)
  333. .then((res) => {
  334. clearInterval(this.timer);
  335. this.loading = false;
  336. if (res.status === 1) {
  337. this.courseTotal = res.data.total;
  338. this.searchList = res.data.results;
  339. }
  340. })
  341. .catch(() => {
  342. this.loading = false;
  343. clearInterval(this.timer);
  344. });
  345. },
  346. changeSelectIndex(val) {
  347. this.selectIndex = val;
  348. },
  349. },
  350. //生命周期 - 创建完成(可以访问当前this实例)
  351. created() {
  352. if (this.config) {
  353. let arr = this.config.split("&&&");
  354. this.LoginNavIndex = arr[0] * 1;
  355. this.userBg = arr[1];
  356. this.headerBorder = arr[2];
  357. this.headerBg = arr[3];
  358. }
  359. this.getStudyList();
  360. this.getYearList();
  361. this.searchArticle();
  362. },
  363. //生命周期 - 挂载完成(可以访问DOM元素)
  364. mounted() {},
  365. //生命周期-创建之前
  366. beforeCreated() {},
  367. //生命周期-挂载之前
  368. beforeMount() {},
  369. //生命周期-更新之前
  370. beforUpdate() {},
  371. //生命周期-更新之后
  372. updated() {},
  373. //生命周期-销毁之前
  374. beforeDestory() {
  375. clearInterval(this.timer);
  376. },
  377. //生命周期-销毁完成
  378. destoryed() {},
  379. //如果页面有keep-alive缓存功能,这个函数会触发
  380. activated() {},
  381. };
  382. </script>
  383. <style lang="scss" scoped>
  384. /* @import url(); 引入css类 */
  385. .search-detail {
  386. width: 100%;
  387. .banner {
  388. width: 100%;
  389. height: 88px;
  390. background: #299772;
  391. position: relative;
  392. .goback {
  393. position: absolute;
  394. left: 24px;
  395. top: 24px;
  396. width: 96px;
  397. height: 40px;
  398. display: block;
  399. text-align: center;
  400. cursor: pointer;
  401. color: #ffffff;
  402. line-height: 40px;
  403. .el-icon-arrow-left {
  404. width: 24px;
  405. height: 24px;
  406. text-align: center;
  407. line-height: 24px;
  408. margin: 0 4px;
  409. }
  410. }
  411. .banner-inner {
  412. width: 868px;
  413. height: 100%;
  414. display: flex;
  415. align-items: center;
  416. justify-content: center;
  417. margin: 0 auto;
  418. position: relative;
  419. > img {
  420. width: 40px;
  421. margin-right: 24px;
  422. position: absolute;
  423. left: 50%;
  424. top: 24px;
  425. margin-left: -434px;
  426. }
  427. .search-compent {
  428. position: absolute;
  429. top: 16px;
  430. }
  431. }
  432. }
  433. .main {
  434. width: 100%;
  435. background: #ffffff;
  436. max-height: calc(100vh - 160px);
  437. overflow-y: scroll;
  438. &::-webkit-scrollbar {
  439. display: none;
  440. }
  441. .typelist {
  442. margin: 32px 0;
  443. padding: 0;
  444. list-style: none;
  445. display: flex;
  446. justify-content: space-between;
  447. li {
  448. width: 200px;
  449. height: 48px;
  450. border-radius: 30px;
  451. padding: 12px 24px;
  452. display: flex;
  453. align-items: center;
  454. cursor: pointer;
  455. border: 1px solid #e5e6eb;
  456. &.active {
  457. border-color: #3459d2;
  458. background: #eef3ff;
  459. .icon-img,
  460. span {
  461. color: #175dff;
  462. }
  463. b {
  464. color: #ed5f00;
  465. }
  466. }
  467. svg {
  468. width: 24px;
  469. height: 24px;
  470. margin-right: 16px;
  471. }
  472. span {
  473. color: #2f3742;
  474. font-weight: 700;
  475. font-size: 16px;
  476. line-height: 24px;
  477. flex: 1;
  478. }
  479. b {
  480. color: #929ca8;
  481. font-weight: 700;
  482. font-size: 16px;
  483. line-height: 24px;
  484. }
  485. }
  486. }
  487. .main-inner {
  488. width: 1200px;
  489. margin: 0 auto;
  490. // border-radius: 8px;
  491. padding: 34px 40px;
  492. ul {
  493. list-style: none;
  494. display: flex;
  495. flex-flow: wrap;
  496. padding: 0;
  497. margin: 0;
  498. li {
  499. padding: 8px 15px;
  500. cursor: pointer;
  501. margin: 6px 16px 6px 0;
  502. font-weight: 400;
  503. font-size: 16px;
  504. line-height: 22px;
  505. color: #2f3742;
  506. &.active {
  507. background: #e7eeff;
  508. border-radius: 4px;
  509. color: #175dff;
  510. }
  511. }
  512. }
  513. .searchChangebox {
  514. margin-top: 13px;
  515. display: flex;
  516. > div {
  517. display: flex;
  518. align-items: center;
  519. justify-content: space-between;
  520. padding: 8px 15px;
  521. height: 38px;
  522. margin-right: 16px;
  523. border-radius: 4px;
  524. &.active {
  525. background: #e7eeff;
  526. > span {
  527. color: #175dff;
  528. }
  529. .sort {
  530. > div {
  531. svg {
  532. &.active {
  533. color: #175dff;
  534. }
  535. }
  536. }
  537. }
  538. }
  539. > span {
  540. font-weight: 400;
  541. font-size: 16px;
  542. line-height: 22px;
  543. color: #2f3742;
  544. margin-right: 8px;
  545. }
  546. .sort {
  547. cursor: pointer;
  548. height: 20px;
  549. > div {
  550. font-size: 0;
  551. svg {
  552. width: 11px;
  553. height: 11px;
  554. color: #c2c2c2;
  555. padding: 3px 2px 2px 2px;
  556. &.icon-down {
  557. height: 9px;
  558. padding: 0 2px 2px 2px;
  559. }
  560. }
  561. }
  562. }
  563. }
  564. }
  565. .timeconsume {
  566. margin: 21px 0 0;
  567. font-weight: 400;
  568. font-size: 14px;
  569. line-height: 22px;
  570. color: rgba(0, 0, 0, 0.4);
  571. }
  572. .search-item {
  573. margin: 24px 0 50px 0;
  574. width: 100%;
  575. display: flex;
  576. cursor: pointer;
  577. .el-image {
  578. width: 110px;
  579. height: 110px;
  580. margin-right: 24px;
  581. }
  582. .search-inner {
  583. flex: 1;
  584. .top {
  585. display: flex;
  586. h2 {
  587. font-weight: 700;
  588. font-size: 16px;
  589. line-height: 24px;
  590. color: #2f3742;
  591. margin: 0 16px 0 0;
  592. font-family: "Rubik";
  593. }
  594. span {
  595. font-weight: 400;
  596. font-size: 16px;
  597. line-height: 24px;
  598. color: #929ca8;
  599. }
  600. }
  601. .content {
  602. margin: 8px 0;
  603. word-break: break-word;
  604. text-overflow: ellipsis;
  605. display: -webkit-box;
  606. -webkit-box-orient: vertical;
  607. -webkit-line-clamp: 2; /* 超出几行省略 */
  608. overflow: hidden;
  609. color: #2f3742;
  610. font-weight: 400;
  611. font-size: 16px;
  612. line-height: 24px;
  613. height: 48px;
  614. }
  615. .bottom {
  616. span {
  617. font-weight: 400;
  618. font-size: 16px;
  619. line-height: 24px;
  620. color: #929ca8;
  621. margin-right: 16px;
  622. }
  623. }
  624. }
  625. }
  626. .search-list {
  627. display: flex;
  628. flex-flow: wrap;
  629. width: 100%;
  630. .search-items {
  631. width: 200px;
  632. margin: 24px 30px 24px 0;
  633. flex-shrink: 0;
  634. &.margin0 {
  635. margin-right: 0;
  636. }
  637. .el-image {
  638. width: 200px;
  639. height: 280px;
  640. flex-shrink: 0;
  641. margin: 0;
  642. }
  643. .periodicalNumber {
  644. font-weight: 400;
  645. font-size: 14px;
  646. line-height: 22px;
  647. color: #2f3742;
  648. margin: 12px 12px 4px 12px;
  649. white-space: nowrap;
  650. overflow: hidden;
  651. text-overflow: ellipsis;
  652. }
  653. .date {
  654. font-size: 12px;
  655. line-height: 20px;
  656. color: #929ca8;
  657. margin: 0 12px 12px 12px;
  658. }
  659. .price {
  660. margin: 0 12px;
  661. align-items: flex-end;
  662. display: flex;
  663. :nth-child(1) {
  664. font-weight: 700;
  665. font-size: 14px;
  666. line-height: 22px;
  667. color: #ec5e41;
  668. }
  669. :nth-child(2) {
  670. font-weight: 400;
  671. font-size: 12px;
  672. line-height: 20px;
  673. text-decoration-line: line-through;
  674. color: #929ca8;
  675. margin-left: 8px;
  676. }
  677. }
  678. }
  679. }
  680. }
  681. }
  682. }
  683. </style>
  684. <style lang="scss">
  685. .search-detail {
  686. .lightbg {
  687. background: #fff500;
  688. }
  689. }
  690. </style>