mobile.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <template>
  2. <section v-if="vipDetail" class="vip">
  3. <section class="banners-box" @touchstart="touchStart" @touchend="touchEnd">
  4. <section class="banners" :class="{'banners-com': currentCom}">
  5. <section class="banner">
  6. <img src="~@/assets/img/vip/vip.png" class="card">
  7. <section class="header">
  8. <section style="position: relative;">
  9. <img :src="userInfo.icon_url" class="avator">
  10. <img v-if="vipNow && !isCom" src="~@/assets/img/vip/vip_icon.png" class="diamond">
  11. </section>
  12. <section>
  13. <span class="name">{{userInfo.nickname}}</span>
  14. <br>
  15. <span v-if="isCom" class="date">暂未开通</span>
  16. <span v-else class="date">{{endTimeCalc}}</span>
  17. </section>
  18. </section>
  19. <section v-if="deviceType !== 'ios'">
  20. <button v-if="!vipNow" class="renewal-fee" @click="clickPay(dev)">开通</button>
  21. <button v-else-if="isCom" disabled class="renewal-fee disabled">开通</button>
  22. <button v-else class="renewal-fee" @click="clickPay(dev)">{{vipNow ? '续费' : '开通'}}</button>
  23. </section>
  24. </section>
  25. <section class="banner">
  26. <img src="~@/assets/img/vip/vip_com.png" class="card">
  27. <section class="header">
  28. <section style="position: relative;">
  29. <img :src="userInfo.icon_url" class="avator avator-com">
  30. <img v-if="vipNow && isCom" src="~@/assets/img/vip/vip_icon_com.png" class="diamond">
  31. </section>
  32. <section>
  33. <span class="name">{{userInfo.nickname}}</span>
  34. <br>
  35. <span v-if="isCom" class="date">{{endTimeCalc}}</span>
  36. <span v-else class="date">暂未开通</span>
  37. </section>
  38. </section>
  39. <section v-if="deviceType !== 'ios'">
  40. <button v-if="!vipNow" class="renewal-fee renewal-fee-com" @click="clickPay(com)">开通</button>
  41. <button v-else-if="isCom" class="renewal-fee renewal-fee-com" @click="clickPay(com)">
  42. {{vipNow ? '续费' :
  43. '开通'}}
  44. </button>
  45. <button v-else disabled class="renewal-fee disabled">开通</button>
  46. </section>
  47. </section>
  48. </section>
  49. <section class="anli-radios">
  50. <div class="anli-radio" :class="{'anli-radio-death': currentCom}"></div>
  51. <div class="anli-radio" :class="{'anli-radio-death': !currentCom}"></div>
  52. </section>
  53. </section>
  54. <section class="block-top">
  55. <section class="list">
  56. <section class="price-box">
  57. <span class="vip">{{currentCom ? '企业会员' : '开发者会员'}}</span>
  58. <span v-if="deviceType !== 'ios'" class="price">
  59. <span class="del" v-if="detail.is_month_discount">原价¥{{detail.monthly_origin_price}}/月</span>
  60. <span class="money">
  61. ¥{{detail.monthly_real_price}}
  62. <span class="mouth">/月</span>
  63. </span>
  64. </span>
  65. </section>
  66. <div class="prices" v-if="deviceType !== 'ios'">
  67. 按季付费
  68. <span style="color: #333;">¥{{detail.quarterly_real_price}}</span>
  69. </div>
  70. </section>
  71. <ul class="project" :class="{ 'is-com': currentCom }">
  72. <li>
  73. <span>· 整包项目-平台服务费(减免{{detail.project_reduction_rate}}%)</span>
  74. <div v-show="currentCom" class="right">
  75. <img src="~@/assets/img/vip/tag_com.png" class="sale">
  76. <span class="discount">{{detail.project_discount}}折</span>
  77. </div>
  78. <div v-show="!currentCom" class="right">
  79. <img src="~@/assets/img/vip/tag.png" class="sale">
  80. <span class="discount">{{detail.project_discount}}折</span>
  81. </div>
  82. </li>
  83. <li>
  84. <span>· 云端工作-平台服务费(减免{{detail.job_reduction_rate}}%)</span>
  85. <div v-show="currentCom" class="right">
  86. <img src="~@/assets/img/vip/tag_com.png" class="sale">
  87. <span class="discount">{{detail.job_discount}}折</span>
  88. </div>
  89. <div v-show="!currentCom" class="right">
  90. <img src="~@/assets/img/vip/tag.png" class="sale">
  91. <span class="discount">{{detail.job_discount}}折</span>
  92. </div>
  93. </li>
  94. <li>
  95. <span v-if="currentCom">· 每天50次程序员聊天次数</span>
  96. <span v-else>· 认证的自由开发者可同时接两单</span>
  97. <img v-show="currentCom" src="~@/assets/img/vip/check_com.png" class="yes">
  98. <img v-show="!currentCom" src="~@/assets/img/vip/check.png" class="yes">
  99. </li>
  100. <li>
  101. <span v-if="currentCom">· 优先推荐对接优质的开发者</span>
  102. <span v-else>· Ping接单意愿权重更高</span>
  103. <img v-show="currentCom" src="~@/assets/img/vip/check_com.png" class="yes">
  104. <img v-show="!currentCom" src="~@/assets/img/vip/check.png" class="yes">
  105. </li>
  106. </ul>
  107. </section>
  108. <section class="block-bottom">
  109. <div class="member-Description">会员说明</div>
  110. <ul class="member">
  111. <li class="li">1.购买会员按季付费;</li>
  112. <li class="li">2.开通会员即代表您已同意《程序员客栈会员服务条款》</li>
  113. <li class="li">3.如有任何问题,欢迎咨询在线客服,或拨打热线:0571-28120931 转1。</li>
  114. </ul>
  115. </section>
  116. </section>
  117. </template>
  118. <script>
  119. let touchX = 0
  120. export default {
  121. props: ['com', 'dev'],
  122. data() {
  123. return {
  124. // 当前是企业页
  125. currentCom: false,
  126. // 会员详情
  127. vipDetail: null,
  128. // 设备类型pc,ios,android
  129. deviceType: 'pc'
  130. }
  131. },
  132. computed: {
  133. endTimeCalc() {
  134. return this.vipNow ? '有效期至' + this.userInfo.vip_end_date : '暂未开通'
  135. },
  136. detail() {
  137. return (this.currentCom ? this.com : this.dev) || {}
  138. },
  139. vipNow() {
  140. return this.vipDetail.is_vip
  141. },
  142. vipInfo() {
  143. return this.vipDetail.vip_info
  144. },
  145. userInfo() {
  146. return this.vipDetail.user_info
  147. },
  148. isCom() {
  149. if (this.$route.query.isCom) return true
  150. return this.vipDetail.vip_type_id !== '2'
  151. },
  152. },
  153. mounted() {
  154. this.getVipDetail();
  155. this.getDeviceType();
  156. },
  157. methods: {
  158. /**
  159. * 设备判断
  160. */
  161. getDeviceType() {
  162. if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { //判断iPhone|iPad|iPod|iOS
  163. this.deviceType = 'ios';
  164. } else if (/(Android)/i.test(navigator.userAgent)) { //判断Android
  165. this.deviceType = 'android';
  166. } else { //pc
  167. };
  168. },
  169. /**
  170. * 点击开通
  171. */
  172. clickPay(item) {
  173. location.href = 'proginn://pay?product_type=11&number=3&product_id=' + item.id
  174. },
  175. /**
  176. * 手指右划
  177. */
  178. swipeRight() {
  179. this.currentCom = false
  180. },
  181. /**
  182. * 手指左划
  183. */
  184. swipeLeft() {
  185. this.currentCom = true
  186. },
  187. touchStart(e) {
  188. touchX = e.touches[0].clientX
  189. },
  190. touchEnd(e) {
  191. var offsetX = e.changedTouches[0].clientX - touchX
  192. if (offsetX < -50) this.swipeLeft()
  193. else if (offsetX > 50) this.swipeRight()
  194. },
  195. /**
  196. * 点击会员计划
  197. */
  198. clickProject(index) {
  199. const vip = this.vipDetail[index];
  200. window.open(recommend.seo_uri);
  201. },
  202. /**
  203. * 获取会员详情
  204. */
  205. async getVipDetail() {
  206. let res = await this.$post('/api/vip/getVipUserDetail')
  207. if (!res.data) return
  208. this.vipDetail = res.data
  209. if (this.isCom) this.currentCom = true
  210. }
  211. },
  212. }
  213. </script>
  214. <style scoped>
  215. .vip {
  216. flex-direction: column;
  217. }
  218. .banners-box {
  219. position: relative;
  220. width: 100%;
  221. height: 145px;
  222. overflow: hidden;
  223. }
  224. .banners {
  225. position: absolute;
  226. top: 0;
  227. left: 0;
  228. width: calc(200% - 30px);
  229. height: 145px;
  230. transform: translate(0, 0);
  231. transition: transform 0.2s linear;
  232. }
  233. .banners-com {
  234. transform: translate(calc(-50% + 40px), 0);
  235. }
  236. .banner {
  237. position: absolute;
  238. left: 0;
  239. top: 0;
  240. display: flex;
  241. justify-content: space-between;
  242. align-items: center;
  243. width: 50%;
  244. height: 145px;
  245. padding: 43px 40px 0 25px;
  246. box-sizing: border-box;
  247. background: #1d1e1f;
  248. z-index: -2;
  249. }
  250. .banner:nth-child(2) {
  251. left: calc(50% - 15px);
  252. }
  253. .card {
  254. position: absolute;
  255. left: 10px;
  256. top: 0;
  257. width: 91%;
  258. height: 100%;
  259. z-index: -1;
  260. }
  261. .avator {
  262. width: 55px;
  263. height: 55px;
  264. border-radius: 28px;
  265. border: 2px solid #e1a83f;
  266. left: 20px;
  267. top: 57px;
  268. }
  269. .diamond {
  270. width: 16px;
  271. height: 16px;
  272. position: absolute;
  273. left: 40px;
  274. top: 40px;
  275. }
  276. .renewal-fee {
  277. width: 77px;
  278. height: 32px;
  279. border-radius: 16px;
  280. background: #e1a83f;
  281. color: white;
  282. font-size: 13px;
  283. font-weight: 300;
  284. left: 262px;
  285. top: 80px;
  286. border: 0;
  287. }
  288. .disabled {
  289. background: grey;
  290. }
  291. .name {
  292. color: black;
  293. font-weight: 460;
  294. font-size: 16px;
  295. left: 92px;
  296. top: 74px;
  297. margin-left: 10px;
  298. }
  299. .date {
  300. color: black;
  301. font-weight: 200;
  302. font-size: 9px;
  303. left: 92px;
  304. top: 100px;
  305. margin-left: 10px;
  306. }
  307. .block-top {
  308. padding: 20px 10px;
  309. background: white;
  310. }
  311. .list {
  312. display: flex;
  313. flex-direction: column;
  314. border-bottom: 0.5px solid rgba(0, 0, 0, 0.06);
  315. }
  316. .vip {
  317. font-size: 14px;
  318. color: rgba(34, 34, 34, 1);
  319. font-weight: 800;
  320. }
  321. .price-box {
  322. display: flex;
  323. justify-content: space-between;
  324. align-items: center;
  325. }
  326. .price {
  327. font-size: 11px;
  328. color: rgba(145, 154, 167, 1);
  329. }
  330. .prices {
  331. display: flex;
  332. justify-content: flex-end;
  333. align-items: center;
  334. font-size: 12px;
  335. font-family: PingFangSC-Regular;
  336. color: #666;
  337. line-height: 33px;
  338. }
  339. .del {
  340. text-decoration: line-through;
  341. }
  342. .money {
  343. font-size: 22px;
  344. color: rgba(34, 34, 34, 1);
  345. font-weight: 800;
  346. }
  347. .mouth {
  348. font-size: 12px;
  349. color: rgba(34, 34, 34, 1);
  350. }
  351. .project {
  352. list-style: none;
  353. padding: 0;
  354. }
  355. li {
  356. display: flex;
  357. justify-content: space-between;
  358. align-items: center;
  359. font-size: 14px;
  360. font-weight: 400;
  361. color: rgba(29, 42, 58, 1);
  362. margin: 12px 0;
  363. height: 24px;
  364. }
  365. .right {
  366. position: relative;
  367. display: flex;
  368. justify-content: center;
  369. align-items: center;
  370. }
  371. .sale {
  372. height: 22px;
  373. width: 51px;
  374. }
  375. .discount {
  376. position: absolute;
  377. left: 6px;
  378. top: 5px;
  379. font-size: 11px;
  380. color: rgba(225, 168, 63, 1);
  381. }
  382. .yes {
  383. width: 15px;
  384. height: 10px;
  385. margin-right: 18px;
  386. }
  387. .block-bottom {
  388. margin: 8px 0 0 0;
  389. padding: 26px 10px 7px 10px;
  390. background: white;
  391. }
  392. .member-Description {
  393. font-size: 14px;
  394. font-weight: 600;
  395. color: #222222;
  396. }
  397. .li {
  398. font-size: 13px;
  399. color: rgba(145, 154, 167, 1);
  400. line-height: 28px;
  401. font-weight: 400;
  402. }
  403. .member {
  404. padding-inline-start: 0px;
  405. }
  406. .header {
  407. display: flex;
  408. align-items: center;
  409. }
  410. .avator-com {
  411. border: 2px solid #308eff;
  412. }
  413. .is-com .discount {
  414. color: #308eff;
  415. }
  416. .renewal-fee-com {
  417. background: #308eff;
  418. }
  419. .anli-radios {
  420. position: absolute;
  421. bottom: 8px;
  422. display: flex;
  423. justify-content: center;
  424. width: 100%;
  425. text-align: center;
  426. z-index: 2;
  427. }
  428. .anli-radio {
  429. width: 16px;
  430. height: 4px;
  431. border: 0;
  432. border-radius: 2px;
  433. margin: 0 2px;
  434. outline: none;
  435. cursor: pointer;
  436. background: rgba(200, 200, 200, 0.8);
  437. }
  438. .anli-radio-death {
  439. width: 8px;
  440. background: rgba(200, 200, 200, 0.4);
  441. }
  442. </style>