mobile.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. <template>
  2. <div class="wrapper" v-if="detail">
  3. <div class="switch-bar" :class="active===0?'switch-bar-brown':current===0?'switch-bar-blue':'switch-bar-green'">
  4. <div class="switch-item" :class="{'switch-item-active':active===0}" @click="handleSwitchClick(0)">
  5. <div class="switch-item-title">开发者会员</div>
  6. <div class="switch-item-border"/>
  7. </div>
  8. <div class="switch-item" :class="{'switch-item-active':active===1}" @click="handleSwitchClick(1)">
  9. <div class="switch-item-title">企业会员</div>
  10. <div class="switch-item-border"/>
  11. </div>
  12. </div>
  13. <div class="banner-brown-wrapper" v-show="active===0">
  14. <div class="banner-brown">
  15. <div class="banner-content">
  16. <div class="avatar">
  17. <img :src="userInfo.icon_url" alt="">
  18. </div>
  19. <div class="name-wrapper">
  20. <div class="name">{{userInfo.nickname}}</div>
  21. <div class="validity">{{vipType === 2 ? endTimeCalc :'暂未开通'}}</div>
  22. </div>
  23. <div class="renew-btn" :class="vipColor" @click="clickPay('dev')">{{vipType === 2 ? '续费' : '开通'}}</div>
  24. </div>
  25. </div>
  26. </div>
  27. <div v-swiper:mySwiper="swiperOption" v-show="active===1">
  28. <div class="swiper-wrapper">
  29. <div class="swiper-slide">
  30. <div class="banner-blue-wrapper">
  31. <div class="banner-blue">
  32. <div class="banner-content">
  33. <div class="avatar">
  34. <img :src="userInfo.icon_url" alt="">
  35. </div>
  36. <div class="name-wrapper">
  37. <div class="name">{{userInfo.nickname}}</div>
  38. <div class="validity">{{vipType ===1 ? endTimeCalc : '暂未开通'}}</div>
  39. </div>
  40. <div class="renew-btn" :class="vipColor" @click="clickPay('com')">{{vipType === 1 ? '续费' : '开通'}}</div>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. <div class="swiper-slide">
  46. <div class="banner-green-wrapper">
  47. <div class="banner-green">
  48. <div class="banner-content">
  49. <div class="avatar">
  50. <img :src="userInfo.icon_url" alt="">
  51. </div>
  52. <div class="name-wrapper">
  53. <div class="name">{{userInfo.nickname}}</div>
  54. <div class="validity">{{vipType ===3 ? endTimeCalc : '暂未开通'}}</div>
  55. </div>
  56. <div class="renew-btn" :class="vipColor" @click="clickPay('pre')">{{vipType === 3 ? '续费' : '开通'}}</div>
  57. </div>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. <div class="swiper-pagination swiper-pagination-bullets"></div>
  63. </div>
  64. <div class="content">
  65. <div class="title-wrapper">
  66. <div class="title">{{vipName}}</div>
  67. <div class="price-wrapper">
  68. <div class="monthly-price-wrapper">
  69. <div class="monthly-origin-price">原价¥{{detail.monthly_origin_price}}/月</div>
  70. <div class="monthly-discount-price"><span>¥{{detail.monthly_real_price}}</span>/月</div>
  71. </div>
  72. <div class="quarterly-price">按季付费 <span>¥{{detail.quarterly_real_price}}</span></div>
  73. </div>
  74. </div>
  75. <div class="list" v-show="active===0">
  76. <div class="item">
  77. <div class="item-title">· 整包项目-平台服务费(减免{{detail.project_reduction_rate}}%)</div>
  78. <div class="item-discount">{{detail.project_discount}}折</div>
  79. </div>
  80. <div class="item">
  81. <div class="item-title">· 云端工作-平台服务费(减免{{detail.job_reduction_rate}}%)</div>
  82. <div class="item-discount">{{detail.job_discount}}折</div>
  83. </div>
  84. <div class="item">
  85. <div class="item-title">· 认证的云端开发者可同时接两单</div>
  86. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  87. </div>
  88. <div class="item">
  89. <div class="item-title"> · 专属VIP服务顾问</div>
  90. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  91. </div>
  92. </div>
  93. <div class="list" v-show="active===1 && current===0">
  94. <div class="item">
  95. <div class="item-title">· 整包项目-平台服务费(减免{{detail.project_reduction_rate}}%)</div>
  96. <div class="item-discount">{{detail.project_discount}}折</div>
  97. </div>
  98. <div class="item">
  99. <div class="item-title">· 云端工作-平台服务费(减免{{detail.job_reduction_rate}}%)</div>
  100. <div class="item-discount">{{detail.job_discount}}折</div>
  101. </div>
  102. <div class="item">
  103. <div class="item-title">· 每天{{detail.chat_times}}次程序员聊天次数</div>
  104. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  105. </div>
  106. <div class="item">
  107. <div class="item-title"> · 每天{{detail.hire_times}}次雇佣项目发布次数</div>
  108. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  109. </div>
  110. <div class="item">
  111. <div class="item-title"> · 免费进行企业认证</div>
  112. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  113. </div>
  114. </div>
  115. <div class="list" v-show="active===1 && current===1">
  116. <div class="item">
  117. <div class="item-title">· 整包项目-平台服务费(减免{{detail.project_reduction_rate}}%)</div>
  118. <div class="item-discount">{{detail.project_discount}}折</div>
  119. </div>
  120. <div class="item">
  121. <div class="item-title">· 云端工作-平台服务费(减免{{detail.job_reduction_rate}}%)</div>
  122. <div class="item-discount">{{detail.job_discount}}折</div>
  123. </div>
  124. <div class="item">
  125. <div class="item-title">· 每天不限次程序员聊天次数</div>
  126. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  127. </div>
  128. <div class="item">
  129. <div class="item-title"> · 每天{{detail.hire_times}}次雇佣项目发布次数</div>
  130. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  131. </div>
  132. <div class="item">
  133. <div class="item-title"> · 免费进行企业认证</div>
  134. <img class="item-include" src="@/assets/img/vip/icon_include_brown.png" alt="">
  135. </div>
  136. </div>
  137. <div class="tips-wrapper">
  138. <div class="tips-title">会员说明</div>
  139. <div class="tips-content">
  140. <p>1.购买会员按季付费;</p>
  141. <p> 2.开通会员即代表您已同意《程序员客栈会员服务条款》;</p>
  142. <p>3.如有任何问题,欢迎咨询在线客服,或拨打热线:0571-28120931 转1。</p>
  143. </div>
  144. </div>
  145. </div>
  146. <buy-dialog
  147. :handleClose="handleClose"
  148. :buyDialog="buyDialog"
  149. :gotoPay="gotoPay"
  150. :type="type"
  151. :item="detail"
  152. :vipDetail="vipDetail"
  153. :pricePrefix="pricePrefix"
  154. ></buy-dialog>
  155. </div>
  156. </template>
  157. <script>
  158. let touchX = 0;
  159. import getDeviceType from "@/mixins/getDeviceType";
  160. import qs from "qs";
  161. import buyDialog from "./buy-dialog";
  162. export default {
  163. props: ["com", "dev", 'pre', "vipDetail"],
  164. data() {
  165. const _this = this
  166. return {
  167. active: 0,
  168. current: 0,
  169. swiperOption: {
  170. loop: false,
  171. slidesPerView: 'auto',
  172. centeredSlides: true,
  173. spaceBetween: 30,
  174. pagination: {
  175. el: '.swiper-pagination',
  176. dynamicBullets: true
  177. },
  178. on: {
  179. slideChange() {
  180. _this.current = this.realIndex
  181. if (window.appBridge && _this.active === 1 && _this.current === 0) {
  182. window.appBridge.setTitleBarColor('#308EFF');
  183. _this.currentType = 1;
  184. } else if (window.appBridge && _this.active === 1 && _this.current === 1) {
  185. window.appBridge.setTitleBarColor('#00BF66');
  186. _this.currentType = 3;
  187. }
  188. },
  189. }
  190. },
  191. buyDialog: false,
  192. type: "com", // com: 企业会员, dev: 开发者会员
  193. currentType: 2,
  194. };
  195. },
  196. components: {
  197. buyDialog
  198. },
  199. mixins: [getDeviceType],
  200. computed: {
  201. endTimeCalc() {
  202. return "有效期至" + this.userInfo.vip_end_date;
  203. },
  204. detail() {
  205. if (this.active === 0) {
  206. return this.dev;
  207. } else if (this.active === 1) {
  208. if (this.current === 0) {
  209. return this.com;
  210. } else if (this.current === 1) {
  211. return this.pre;
  212. }else {
  213. return [];
  214. }
  215. }
  216. },
  217. vipType() {
  218. return this.userInfo.vip_type || 0;
  219. },
  220. userInfo() {
  221. return this.vipDetail.user_info || {};
  222. },
  223. pricePrefix() {
  224. return this.deviceType === "ios" ? "apple_" : "";
  225. },
  226. vipName() {
  227. if (this.active === 0) {
  228. return '开发者会员';
  229. } else if (this.active === 1) {
  230. if (this.current === 0) {
  231. return '初创版会员';
  232. } else if (this.current === 1) {
  233. return '企业版会员'
  234. }
  235. }
  236. },
  237. vipColor() {
  238. if (this.active === 0) {
  239. return 'yellow';
  240. } else if (this.active === 1) {
  241. if (this.current === 0) {
  242. return 'blue';
  243. } else if (this.current === 1) {
  244. return 'green'
  245. }
  246. }
  247. }
  248. },
  249. mounted() {
  250. const activeName = this.$route.query.activeName
  251. if (activeName==='enterprise') {
  252. this.active = 1
  253. } else {
  254. this.active = 0
  255. }
  256. if (window.appBridge && this.active === 0) {
  257. window.appBridge.setTitleBarColor('#D89823')
  258. } else if (window.appBridge && this.active === 1 && this.current === 0) {
  259. window.appBridge.setTitleBarColor('#308EFF')
  260. } else if (window.appBridge && this.active === 1 && this.current === 1) {
  261. window.appBridge.setTitleBarColor('#00BF66')
  262. }
  263. },
  264. methods: {
  265. clickPay(type) {
  266. this.type = type;
  267. this.buyDialog = true;
  268. // location.href = `/vip/pay?product_id=${item.id}&number=3&next=/type/vip/`;
  269. },
  270. handleClose() {
  271. this.buyDialog = false;
  272. },
  273. async gotoPay(number) {
  274. const item = this[this.type];
  275. let query = {
  276. product_type: 11,
  277. number: number,
  278. product_id: item.id
  279. };
  280. if (this.deviceType === "ios") {
  281. // alert('ios begin pay..');
  282. let cookie = this.getSign();
  283. let res = await this.$axios.$post("/api/vip/pay", {
  284. product_type: 11,
  285. number: number,
  286. product_id: item.id,
  287. channel: "apple",
  288. needLogin: true,
  289. ...cookie
  290. });
  291. if (res && res.data) {
  292. query = Object.assign({}, query, res.data);
  293. location.href = "proginn://pay?" + qs.stringify(query);
  294. }
  295. } else {
  296. location.href = "proginn://pay?" + qs.stringify(query);
  297. }
  298. },
  299. /**
  300. * 手指右划
  301. */
  302. swipeRight() {
  303. this.currentCom = false;
  304. },
  305. /**
  306. * 手指左划
  307. */
  308. swipeLeft() {
  309. this.currentCom = true;
  310. },
  311. touchStart(e) {
  312. touchX = e.touches[0].clientX;
  313. },
  314. touchEnd(e) {
  315. var offsetX = e.changedTouches[0].clientX - touchX;
  316. if (offsetX < -50) this.swipeLeft();
  317. else if (offsetX > 50) this.swipeRight();
  318. },
  319. handleSwitchClick(index) {
  320. this.active = index
  321. if (window.appBridge) {
  322. if (this.active === 0) {
  323. window.appBridge.setTitleBarColor('#D89823');
  324. } else if (this.active === 1 && this.current === 0) {
  325. window.appBridge.setTitleBarColor('#308EFF');
  326. } else if (this.active === 1 && this.current === 1) {
  327. window.appBridge.setTitleBarColor('#00BF66');
  328. }
  329. }
  330. }
  331. }
  332. };
  333. </script>
  334. <style scoped lang="scss">
  335. @import "~@/assets/css/scssCommon.scss";
  336. .wrapper {
  337. overflow: hidden;
  338. margin-top: 0;
  339. width: 100%;
  340. background-color: #F4F5F9;
  341. }
  342. .switch-bar {
  343. display: flex;
  344. background-color: #D89823;
  345. }
  346. .switch-bar-brown {
  347. background-color: #D89823;
  348. }
  349. .switch-bar-blue {
  350. background-color: #308EFF;
  351. }
  352. .switch-bar-green {
  353. background-color: #00BF66;
  354. }
  355. .switch-item {
  356. flex: 1;
  357. padding-top: remtovw(0.4);
  358. padding-bottom: remtovw(0.15);
  359. }
  360. .switch-item .switch-item-title {
  361. line-height: remtovw(0.42);
  362. text-align: center;
  363. font-size: remtovw(0.3);
  364. color: #FFFFFF;
  365. }
  366. .switch-item .switch-item-border {
  367. margin: remtovw(0.18) auto 0;
  368. width: remtovw(0.6);
  369. height: remtovw(0.06);
  370. background-color: transparent;
  371. }
  372. .switch-item-active .switch-item-title {
  373. font-weight: 600;
  374. }
  375. .switch-item-active .switch-item-border {
  376. background-color: #ffffff;
  377. }
  378. .banner-brown-wrapper {
  379. background-color: #D89823;
  380. }
  381. .banner-brown {
  382. overflow: hidden;
  383. margin: 0 auto;
  384. width: remtovw(7);
  385. height: remtovw(2.9);
  386. background-image: url('~@/assets/img/vip/banner_brown.png');
  387. background-size: 100%;
  388. background-repeat: no-repeat;
  389. }
  390. .banner-blue-wrapper {
  391. background-color: #308EFF;
  392. }
  393. .banner-blue {
  394. overflow: hidden;
  395. margin: 0 auto;
  396. width: remtovw(7);
  397. height: remtovw(2.9);
  398. background-image: url('~@/assets/img/vip/banner_blue.png');
  399. background-size: 100%;
  400. background-repeat: no-repeat;
  401. }
  402. .banner-green-wrapper {
  403. background-color: #00BF66;
  404. }
  405. .banner-green {
  406. overflow: hidden;
  407. margin: 0 auto;
  408. width: remtovw(7);
  409. height: remtovw(2.9);
  410. background-image: url('~@/assets/img/vip/banner_green.png');
  411. background-size: 100%;
  412. background-repeat: no-repeat;
  413. }
  414. .banner-content {
  415. margin-top: remtovw(1.12);
  416. display: flex;
  417. align-items: center;
  418. }
  419. .avatar {
  420. position: relative;
  421. margin-left: remtovw(0.32);
  422. width: remtovw(1.1);
  423. height: remtovw(1.1);
  424. }
  425. .avatar img {
  426. width: 100%;
  427. height: 100%;
  428. border-radius: 50%;
  429. border: remtovw(0.03) solid #E1A83F;
  430. }
  431. .name-wrapper {
  432. flex: 1;
  433. margin-left: remtovw(0.23);
  434. }
  435. .name {
  436. line-height: remtovw(0.48);
  437. font-weight: 500;
  438. font-size: remtovw(0.34);
  439. color: #222222;
  440. }
  441. .validity {
  442. margin-top: remtovw(0.02);
  443. line-height: remtovw(0.3);
  444. font-size: remtovw(0.22);
  445. color: rgba(34, 34, 34, 0.6)
  446. }
  447. .renew-btn {
  448. margin-right: remtovw(0.3);
  449. width: remtovw(1.54);
  450. height: remtovw(0.64);
  451. border-radius: remtovw(0.32);
  452. background-color: #D89823;
  453. line-height: remtovw(0.64);
  454. font-weight: 600;
  455. text-align: center;
  456. font-size: remtovw(0.26);
  457. color: #FFFFFF;
  458. }
  459. .content {
  460. overflow: hidden;
  461. background-color: #FFFFFF;
  462. }
  463. .title-wrapper {
  464. margin: 0 auto;
  465. width: remtovw(7.1);
  466. padding-bottom: remtovw(0.2);
  467. display: flex;
  468. }
  469. .title {
  470. flex: 1;
  471. margin-top: remtovw(.17);
  472. margin-left: remtovw(0.24);
  473. line-height: remtovw(0.75);
  474. font-weight: 600;
  475. font-size: remtovw(0.29);
  476. color: #222222;
  477. }
  478. .price-wrapper {
  479. margin-top: remtovw(0.23);
  480. text-align: right;
  481. }
  482. .monthly-price-wrapper {
  483. display: flex;
  484. }
  485. .monthly-origin-price {
  486. margin-top: remtovw(.17);
  487. line-height: remtovw(0.3);
  488. font-size: remtovw(0.22);
  489. color: #919AA7;
  490. text-decoration: line-through;
  491. }
  492. .monthly-discount-price {
  493. margin-left: remtovw(.07);
  494. line-height: remtovw(0.62);
  495. font-size: remtovw(0.24);
  496. color: #222222;
  497. }
  498. .monthly-discount-price span {
  499. font-weight: 600;
  500. font-size: remtovw(0.45);
  501. }
  502. .quarterly-price {
  503. margin-top: remtovw(0.01);
  504. margin-right: remtovw(0.05);
  505. line-height: remtovw(0.33);
  506. font-size: remtovw(0.24);
  507. color: #666666;
  508. }
  509. .quarterly-price span {
  510. color: #333333;
  511. }
  512. .list {
  513. padding-top: remtovw(0.3);
  514. padding-bottom: remtovw(0.33);
  515. }
  516. .item {
  517. margin: 0 auto;
  518. width: remtovw(7.1);
  519. display: flex;
  520. align-items: center;
  521. }
  522. .item-title {
  523. flex: 1;
  524. line-height: remtovw(0.74);
  525. font-size: remtovw(0.28);
  526. color: #1D2A3A;
  527. }
  528. .item-discount {
  529. width: remtovw(1.02);
  530. height: remtovw(0.44);
  531. background-image: url('~@/assets/img/vip/icon_discount_brown.png');
  532. background-size: 100%;
  533. background-repeat: no-repeat;
  534. line-height: remtovw(0.44);
  535. text-indent: remtovw(0.16);
  536. font-size: remtovw(0.22);
  537. color: #E1A83F;
  538. }
  539. .item-include {
  540. margin-right: remtovw(0.35);
  541. width: remtovw(0.3);
  542. height: remtovw(0.2);
  543. }
  544. .tips-wrapper {
  545. overflow: hidden;
  546. margin-top: remtovw(0.15);
  547. padding-bottom: remtovw(0.39);
  548. background-color: #ffffff;
  549. }
  550. .tips-title {
  551. margin-top: remtovw(0.36);
  552. margin-left: remtovw(0.2);
  553. line-height: remtovw(0.4);
  554. font-weight: 600;
  555. font-size: remtovw(0.28);
  556. color: #666666;
  557. }
  558. .tips-content {
  559. margin-top: remtovw(0.18);
  560. margin-left: remtovw(0.2);
  561. width: remtovw(6.8);
  562. line-height: remtovw(0.56);
  563. font-size: remtovw(0.26);
  564. color: #999999;
  565. }
  566. .green {
  567. background-color: #00BF66;
  568. }
  569. .yellow {
  570. background-color: #D89823;
  571. }
  572. .blue {
  573. background-color: #308EFF;
  574. }
  575. </style>