bookPeruseItem.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. <template>
  2. <div class="bookItem">
  3. <Header
  4. :headerBg="headerBg"
  5. :headerBorder="headerBorder"
  6. :userBg="userBg"
  7. :LoginNavIndex="LoginNavIndex"
  8. ref="header"
  9. />
  10. <div class="navBar" v-if="info">
  11. <div class="navBar-left">
  12. <a class="goback" @click="$router.go(-1)"><i class="el-icon-arrow-left"></i>精读课堂</a>
  13. <div class="border"></div>
  14. <p>{{'第 '+info.batch+' 期'}}{{info.cn_title}}</p>
  15. </div>
  16. <!-- <div class="navBar-right">
  17. <a @click="handleShare">
  18. <svg-icon icon-class="share-personal" className="icon-share"></svg-icon>
  19. <span>分享</span>
  20. </a>
  21. <a @click="handlelike">
  22. <svg-icon icon-class="like-line" className="icon-like"></svg-icon>
  23. <span>收藏</span>
  24. </a>
  25. </div> -->
  26. </div>
  27. <div class="main-top" v-if="info">
  28. <div class="main-top-inner">
  29. <el-carousel class="swiper-container" trigger="click" arrow="never" height="414px">
  30. <!-- <el-carousel-item v-for="(item1, index) in data.imgList" :key="index"> -->
  31. <el-image
  32. class="image"
  33. :src="info.cover_img?info.cover_img:bookType==='baozhi'?require('../../assets/baozhi'+(Math.floor(Math.random()*2)+1)+'.png'):require('../../assets/kecheng'+(Math.floor(Math.random()*3)+1)+'.png')"
  34. :fit="'contain'">
  35. </el-image>
  36. <!-- </el-carousel-item> -->
  37. </el-carousel>
  38. <div class="book-info-right">
  39. <h1 class="title">{{info.cn_title}}</h1>
  40. <!-- <b class="org">{{data.org}}</b><span class="date">2023.07.01-2023.07.21</span> -->
  41. <div class="sales-box" v-if="isBuy==='false'">
  42. <div class="sales-left">
  43. <span>优惠价</span>
  44. <span class="OPPOSans">¥{{info.price|cutMoneyFiter}}</span>
  45. </div>
  46. <span class="sales-right" v-if="sales>=1000">累计销售 {{salesCn}}</span>
  47. </div>
  48. <!-- <div class="book-describe">
  49. <h2 class="title">{{data.describe.title}}</h2>
  50. <span class="author">{{'BY '+data.describe.author}}</span>
  51. <p class="describe">{{data.describe.describe}}</p>
  52. </div> -->
  53. <div class="info-box">
  54. <div class="info-item">
  55. <label>机构</label>
  56. <span>二十一世纪英文报</span>
  57. </div>
  58. <div class="info-item">
  59. <label>学段</label>
  60. <span>{{info.study_phase_name}}版</span>
  61. </div>
  62. <div class="info-item">
  63. <label>期数</label>
  64. <span>{{info.batch}} 期</span>
  65. </div>
  66. <div class="info-item">
  67. <label>有效期</label>
  68. <span>永久有效</span>
  69. </div>
  70. <div class="info-item">
  71. <label>主题</label>
  72. <span>{{info.label}}</span>
  73. </div>
  74. </div>
  75. <div class="btn-box">
  76. <a class="continue" v-if="isBuy==='true'" @click="handleLink">继续学习</a>
  77. <template v-else>
  78. <a class="el-button" @click="handleChangeWay('wei')" :loading="createOrderLoading">立即购买</a>
  79. <a class="upgrade" @click="handleChangeWay('dui')">使用兑换码</a>
  80. <a class="upgrade" @click="linkSubscribe">多期订阅</a>
  81. </template>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. <div class="main-center" v-if="info">
  87. <el-tabs type="card" style="margin-bottom:24px;" v-if="info.introduction">
  88. <el-tab-pane label="简介">
  89. <div v-html="info.introduction"></div>
  90. </el-tab-pane>
  91. </el-tabs>
  92. <div class="banner-box-close" v-if="bannerFlag">
  93. <a v-if="1==2" href="#" target="_blank">
  94. <img class="banner-item" src="../../assets/banner4.png" />
  95. </a>
  96. <img v-else class="banner-item" src="../../assets/banner4.png" />
  97. <div class="close-box">
  98. <a class="close-btn" @click="bannerFlag=false"><i class="el-icon-close"></i></a>
  99. <span class="close-tips">广告</span>
  100. </div>
  101. </div>
  102. </div>
  103. <el-dialog
  104. :visible.sync="paymentShow"
  105. :show-close="false"
  106. :close-on-click-modal="false"
  107. width="712px"
  108. class="bookItem-dialog"
  109. v-if="paymentShow">
  110. <Payment :data="info" :payWay="payWay" @handleClose="handleClose" :orderId="orderId" :qr_code_url="qr_code_url" :order_amount="order_amount" />
  111. </el-dialog>
  112. </div>
  113. </template>
  114. <script>
  115. //这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  116. //例如:import 《组件名称》from ‘《组件路径》';
  117. import Header from "../../components/Header.vue";
  118. import BookCard from "@/components/common/BookCard.vue"
  119. import Payment from "./components/Payment.vue"
  120. import TreeList from "./components/TreeList"
  121. import CourseList from "./components/CourseList.vue"
  122. import { cutMoneyFiter } from '@/utils/defined';
  123. import { getLogin, getNoToken } from "@/api/ajax";
  124. import { getToken } from '@/utils/auth'
  125. export default {
  126. //import引入的组件需要注入到对象中才能使用
  127. components: { Header, BookCard, Payment, TreeList, CourseList },
  128. props: [],
  129. filters:{
  130. cutMoneyFiter
  131. },
  132. data() {
  133. //这里存放数据
  134. return {
  135. config: this.$route.query.headerConfig?decodeURIComponent(this.$route.query.headerConfig):'',
  136. LoginNavIndex: 0,
  137. userBg: 'rgba(0, 0, 0, 0.24)',
  138. headerBorder: '#5C5C5C',
  139. headerBg: '#1F1F1F',
  140. previousPage: '商城',
  141. tagBg:['#C9EBFF','#FFFAC9','#D7C9FF'], // 标签背景色
  142. tagColor:['#006DAA','#AA8500','#7849C4'], // 标签字体颜色
  143. paymentShow: false, // 支付弹窗
  144. payWay:this.$route.query.paywei?this.$route.query.paywei:'dui',
  145. bookType: this.$route.query.cardType?this.$route.query.cardType:'baozhi', // 书籍类型
  146. bannerFlag: true, // 是否展示广告
  147. id: this.$route.query.id?this.$route.query.id:'',
  148. info: null, // 信息
  149. courseList:[],
  150. sales: null,
  151. salesCn: '',
  152. isBuy: 'false',
  153. userMessage: getToken()?JSON.parse(getToken()):null,
  154. orderId: '',
  155. qr_code_url: '',
  156. pre_play_cs_item_id: '', //上次阅读课节id
  157. pre_play_index: null, // 上次阅读索引
  158. order_amount: null,
  159. createOrderLoading: false,
  160. }
  161. },
  162. //计算属性 类似于data概念
  163. computed: {},
  164. //监控data中数据变化
  165. watch: {},
  166. //方法集合
  167. methods: {
  168. // 分享
  169. handleShare(){
  170. },
  171. // 收藏
  172. handlelike(){
  173. },
  174. handleChangeWay(type){
  175. if(!this.userMessage){
  176. this.$refs.header.handleLogin('/bookItem?headerConfig='+this.$route.query.headerConfig+'&cardType='+this.bookType+'&id='+this.id+'&paywei='+type,'url')
  177. return false
  178. }
  179. this.payWay = type;
  180. this.handleOrder()
  181. },
  182. // 关闭弹窗
  183. handleClose(){
  184. this.paymentShow = false
  185. this.getInfo()
  186. },
  187. // 详情
  188. getInfo(){
  189. let MethodName = "/PaperServer/Client/Iread/GetIreadBriefInfo";
  190. let data = {
  191. id: this.id,
  192. }
  193. getLogin(MethodName, data)
  194. .then((res) => {
  195. if(res.status===1){
  196. this.info = res.data
  197. }
  198. })
  199. .catch(() => {
  200. });
  201. if(this.userMessage){
  202. getLogin('/ShopServer/Client/BookshelfQuery/GetGoodsBuyStatus', {
  203. goods_type: 3,
  204. goods_id: this.id
  205. })
  206. .then((res) => {
  207. if(res.status===1){
  208. this.isBuy = res.buy_info.is_buy
  209. this.sales = res.data.sold_count
  210. if(this.sales<1000){
  211. this.salesCn = ''
  212. }else if(1000<=this.sales&&this.sales<10000){
  213. this.salesCn = this.sales.toString().substring(0,1)+'000+'
  214. }else if(10000<=this.sales&&this.sales<100000){
  215. this.salesCn = this.sales.toString().substring(0,1)+'万+'
  216. }else if(100000<=this.sales&&this.sales<1000000){
  217. this.salesCn = this.sales.toString().substring(0,1)+'0万+'
  218. }else if(1000000<=this.sales&&this.sales<10000000){
  219. this.salesCn = this.sales.toString().substring(0,1)+'00万+'
  220. }else if(10000000<=this.sales&&this.sales<100000000){
  221. this.salesCn = this.sales.toString().substring(0,1)+'000万+'
  222. }else if(100000000<=this.sales){
  223. this.salesCn = this.sales.toString().substring(0,1)+'亿+'
  224. }
  225. }
  226. })
  227. .catch(() => {
  228. });
  229. }else{
  230. getNoToken('/ShopServer/Client/BookshelfQuery/GetGoodsBuyStatus', {
  231. goods_type: 3,
  232. goods_id: this.id
  233. }, 'VOID')
  234. .then((res) => {
  235. if(res.status===1){
  236. this.isBuy = res.buy_info.is_buy
  237. this.sales = res.data.sold_count
  238. if(this.sales<1000){
  239. this.salesCn = ''
  240. }else if(1000<=this.sales&&this.sales<10000){
  241. this.salesCn = this.sales.toString().substring(0,1)+'000+'
  242. }else if(10000<=this.sales&&this.sales<100000){
  243. this.salesCn = this.sales.toString().substring(0,1)+'万+'
  244. }else if(100000<=this.sales&&this.sales<1000000){
  245. this.salesCn = this.sales.toString().substring(0,1)+'0万+'
  246. }else if(1000000<=this.sales&&this.sales<10000000){
  247. this.salesCn = this.sales.toString().substring(0,1)+'00万+'
  248. }else if(10000000<=this.sales&&this.sales<100000000){
  249. this.salesCn = this.sales.toString().substring(0,1)+'000万+'
  250. }else if(100000000<=this.sales){
  251. this.salesCn = this.sales.toString().substring(0,1)+'亿+'
  252. }
  253. }
  254. })
  255. .catch(() => {
  256. });
  257. }
  258. },
  259. // 生成订单
  260. handleOrder(){
  261. this.createOrderLoading = true
  262. let MethodName = "/ShopServer/Client/OrderManager/CreateOrder";
  263. let data = {
  264. goods_type: 3,
  265. goods_id_list: [this.id],
  266. pay_type: this.payWay==='wei'?3:this.payWay==='zhi'?4:this.payWay==='dui'?5:null
  267. }
  268. getLogin(MethodName, data)
  269. .then((res) => {
  270. this.createOrderLoading = false
  271. if(res.status === 1){
  272. this.order_amount = res.order_amount
  273. if(this.order_amount<=0){
  274. this.getInfo()
  275. }else{
  276. this.orderId = res.id
  277. this.qr_code_url = res.qr_code_url
  278. this.paymentShow = true;
  279. }
  280. }
  281. }).catch(()=>{
  282. this.createOrderLoading = false
  283. })
  284. // this.paymentShow = true;
  285. },
  286. // 跳转
  287. handleLink(){
  288. let url = this.LoginNavIndex +'&&&'+ this.userBg +'&&&'+ this.headerBorder +'&&&'+ this.headerBg
  289. this.$router.push({
  290. path: "/articlePeruseDetail",
  291. query: {
  292. headerConfig: encodeURIComponent(url),
  293. peruseId: this.id
  294. },
  295. });
  296. },
  297. // 多期订阅
  298. linkSubscribe(){
  299. this.$router.push({
  300. path: "/subscribe",
  301. query: {
  302. name: encodeURIComponent('精读'),
  303. type: 'jingdu',
  304. studyType: this.info.study_phase,
  305. studyTypeName: encodeURIComponent(this.info.study_phase_name)
  306. }
  307. })
  308. }
  309. },
  310. //生命周期 - 创建完成(可以访问当前this实例)
  311. created() {
  312. if(this.config){
  313. let arr = this.config.split('&&&')
  314. this.LoginNavIndex = arr[0] * 1
  315. this.userBg = arr[1] ? arr[1] : 'rgba(0, 0, 0, 0.24)'
  316. this.headerBorder = arr[2] ? arr[2] : '#5C5C5C'
  317. this.headerBg = arr[3] ? arr[3] : '#1F1F1F'
  318. this.previousPage = arr[4] ? arr[4] : '商城'
  319. }
  320. this.getInfo()
  321. if(this.$route.query.paywei){
  322. this.handleOrder()
  323. }
  324. },
  325. //生命周期 - 挂载完成(可以访问DOM元素)
  326. mounted() {
  327. },
  328. //生命周期-创建之前
  329. beforeCreated() { },
  330. //生命周期-挂载之前
  331. beforeMount() { },
  332. //生命周期-更新之前
  333. beforUpdate() { },
  334. //生命周期-更新之后
  335. updated() { },
  336. //生命周期-销毁之前
  337. beforeDestory() { },
  338. //生命周期-销毁完成
  339. destoryed() { },
  340. //如果页面有keep-alive缓存功能,这个函数会触发
  341. activated() { }
  342. }
  343. </script>
  344. <style lang="scss" scoped>
  345. /* @import url(); 引入css类 */
  346. .bookItem {
  347. background: #F7F8FA;
  348. min-height: 100%;
  349. .main-top {
  350. background: #FFFFFF;
  351. padding: 48px 0;
  352. margin-top: 56px;
  353. &-inner{
  354. width: 1200px;
  355. margin: 0 auto;
  356. display: flex;
  357. .swiper-container{
  358. width: 416px;
  359. height: 440px;
  360. text-align: center;
  361. .el-image{
  362. width: 414px;
  363. height: 414px;
  364. border: 1px solid #F3F3F3;
  365. }
  366. }
  367. .book-info-right{
  368. flex: 1;
  369. padding-left: 88px;
  370. .title{
  371. color: #2F3742;
  372. font-weight: 500;
  373. font-size: 32px;
  374. line-height: 44px;
  375. margin: 0 0 16px 0;
  376. }
  377. .org,.date{
  378. font-weight: 500;
  379. font-size: 14px;
  380. line-height: 22px;
  381. color: rgba(0, 0, 0, 0.4);
  382. }
  383. .date{
  384. margin-left: 32px;
  385. line-height: 24px;
  386. }
  387. .label-box{
  388. display: flex;
  389. flex-flow: wrap;
  390. margin: 16px 0;
  391. label{
  392. margin: 0 8px 8px 0;
  393. border-radius: 20px;
  394. padding: 4px 12px;
  395. font-weight: 400;
  396. font-size: 14px;
  397. line-height: 22px;
  398. }
  399. }
  400. .book-describe{
  401. border-top: 1px solid #E5E6EB;
  402. border-bottom: 1px solid #E5E6EB;
  403. padding: 16px 0;
  404. .title{
  405. font-weight: 500;
  406. font-size: 16px;
  407. line-height: 24px;
  408. color: #000000;
  409. margin-bottom: 8px;
  410. }
  411. .author{
  412. font-weight: 400;
  413. font-size: 12px;
  414. line-height: 20px;
  415. color: #000000;
  416. margin-bottom: 8px;
  417. display: block;
  418. }
  419. .describe{
  420. font-weight: 400;
  421. font-size: 14px;
  422. line-height: 22px;
  423. color: #000000;
  424. margin: 0;
  425. }
  426. }
  427. .price-box{
  428. padding: 20px 0 16px 0;
  429. display: flex;
  430. align-items: flex-end;
  431. .price{
  432. font-weight: 500;
  433. font-size: 32px;
  434. line-height: 40px;
  435. color: #EA5939;
  436. }
  437. .oldPrice{
  438. padding: 0 0 2px 7px;
  439. font-weight: 500;
  440. font-size: 14px;
  441. line-height: 22px;
  442. color: rgba(0, 0, 0, 0.4);
  443. text-decoration-line: line-through;
  444. }
  445. }
  446. .info-box{
  447. display: flex;
  448. flex-flow: wrap;
  449. border-bottom: 1px solid #EBEBEB;
  450. margin: 24px 0;
  451. .info-item{
  452. width: 50%;
  453. margin-bottom: 15px;
  454. font-size: 14px;
  455. line-height: 22px;
  456. display: flex;
  457. label{
  458. color: #C2C2C2;
  459. font-weight: 400;
  460. margin-right: 16px;
  461. width: 58px;
  462. display: block;
  463. text-align:justify;
  464. text-justify:distribute-all-lines;
  465. text-align-last:justify;
  466. -moz-text-align-last:justify;
  467. -webkit-text-align-last:justify;
  468. }
  469. }
  470. }
  471. .btn-box{
  472. display: flex;
  473. .el-button{
  474. width: 112px;
  475. height: 40px;
  476. background: #EA5939;
  477. box-shadow: 0px 8px 16px rgba(234, 89, 57, 0.24);
  478. border-radius: 4px;
  479. font-weight: 500;
  480. font-size: 16px;
  481. color: #FFFFFF;
  482. border: none;
  483. }
  484. .svg-icon{
  485. margin-left: 7px;
  486. }
  487. .continue{
  488. width: 112px;
  489. height: 40px;
  490. background: #175DFF;
  491. border-radius: 4px;
  492. font-weight: 500;
  493. font-size: 16px;
  494. line-height: 40px;
  495. color: rgba(255, 255, 255, 1);
  496. display: block;
  497. text-align: center;
  498. box-shadow: 0px 8px 16px rgba(23, 93, 255, 0.24);
  499. }
  500. .upgrade{
  501. margin-left: 16px;
  502. display: block;
  503. padding: 0px 24px;
  504. height: 40px;
  505. background: #E9E9E9;
  506. box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.06);
  507. border-radius: 4px;
  508. color: #595959;
  509. font-weight: 500;
  510. font-size: 16px;
  511. line-height: 40px;
  512. text-align: center;
  513. width: 130px;
  514. }
  515. }
  516. }
  517. }
  518. }
  519. .main-center{
  520. width: 1200px;
  521. margin: 0 auto;
  522. padding: 40px 0;
  523. .el-tabs--card>.el-tabs__header .el-tabs__item.is-active{
  524. border-color: #E7E7E7;
  525. }
  526. }
  527. .main-bottom{
  528. width: 1200px;
  529. margin: 0 auto;
  530. padding-bottom: 40px;
  531. &-top{
  532. display: flex;
  533. justify-content: space-between;
  534. p{
  535. margin: 0;
  536. font-weight: 500;
  537. font-size: 24px;
  538. line-height: 32px;
  539. color: #1F2C5C;
  540. font-family: initial;
  541. }
  542. .right{
  543. color: rgba(0, 0, 0, 0.88);
  544. font-weight: 400;
  545. font-size: 16px;
  546. line-height: 24px;
  547. cursor: pointer;
  548. a{
  549. margin-right: 8px;
  550. }
  551. }
  552. }
  553. }
  554. .list {
  555. margin-top: 24px;
  556. display: flex;
  557. flex-wrap: wrap;
  558. > div {
  559. width: 200px;
  560. border-radius: 8px;
  561. overflow: hidden;
  562. background: #ffffff;
  563. margin-bottom: 24px;
  564. }
  565. }
  566. }
  567. .banner-box-close{
  568. margin-top: 40px;
  569. }
  570. .sales-box{
  571. display: flex;
  572. // width: 592px;
  573. padding: 16px;
  574. border-radius: 4px;
  575. background: #F5F5F5;
  576. justify-content: space-between;
  577. align-items: flex-end;
  578. color: #ADADAD;
  579. font-size: 14px;
  580. font-weight: 400;
  581. line-height: 22px;
  582. .OPPOSans{
  583. margin: 0 8px 0 16px;
  584. color: #EA5939;
  585. font-size: 32px;
  586. font-weight: 500;
  587. line-height: 40px;
  588. }
  589. .old-price{
  590. color: rgba(0, 0, 0, 0.40);
  591. font-size: 14px;
  592. font-weight: 500;
  593. line-height: 22px;
  594. text-decoration: line-through;
  595. }
  596. }
  597. </style>
  598. <style lang="scss">
  599. .bookItem{
  600. .el-carousel__button{
  601. width: 8px;
  602. height: 8px;
  603. background: #D9D9D9;
  604. opacity: 1;
  605. border-radius: 4px;
  606. }
  607. .el-carousel__indicator.is-active{
  608. .el-carousel__button{
  609. background: #5E5E5E;
  610. }
  611. }
  612. .el-tabs__header{
  613. margin: 0;
  614. }
  615. .el-tab-pane{
  616. background: #F8F8F8;
  617. border: 1px solid #E7E7E7;
  618. border-top: none;
  619. padding: 24px;
  620. }
  621. .el-tabs__item{
  622. width: 160px;
  623. height: 38px;
  624. text-align: center;
  625. font-weight: 500;
  626. font-size: 14px;
  627. line-height: 38px;
  628. color: #1F2C5C;
  629. &:hover{
  630. background: #E7E7E7;
  631. }
  632. &.is-active{
  633. // background: #3459D2;
  634. // color: #EEF3FF;
  635. border-bottom: none;
  636. background: #E7E7E7;
  637. }
  638. }
  639. }
  640. .bookitem-dropdown.el-dropdown-menu{
  641. padding: 4px;
  642. .el-dropdown-menu__item{
  643. font-weight: 500;
  644. font-size: 16px;
  645. line-height: 40px;
  646. color: #000000;
  647. }
  648. .el-dropdown-menu__item:focus, .el-dropdown-menu__item:not(.is-disabled):hover{
  649. background: #FDECEE;
  650. border-radius: 4px;
  651. color: #EA5939;
  652. }
  653. }
  654. .bookItem-dialog{
  655. .el-dialog__header,.el-dialog__body{
  656. padding: 0;
  657. }
  658. .el-dialog{
  659. border: 1px solid #EBEBEB;
  660. box-shadow: 0px 6px 30px 5px rgba(0, 0, 0, 0.05), 0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 8px 10px -5px rgba(0, 0, 0, 0.08);
  661. border-radius: 8px;
  662. overflow: hidden;
  663. }
  664. }
  665. </style>