member_recharge.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <!-- +---------------------------------------------------------------------- -->
  2. <!-- | CRMEB [ CRMEB赋能开发者,助力企业发展 ] -->
  3. <!-- +---------------------------------------------------------------------- -->
  4. <!-- | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved. -->
  5. <!-- +---------------------------------------------------------------------- -->
  6. <!-- | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 -->
  7. <!-- +---------------------------------------------------------------------- -->
  8. <!-- | Author: CRMEB Team <admin@crmeb.com> -->
  9. <!-- +---------------------------------------------------------------------- -->
  10. {extend name="public/container"}
  11. {block name="title"}会员管理{/block}
  12. {block name="content"}
  13. <div v-cloak id="app" class="member-recharge">
  14. <div v-if="userInfo" class="user-section">
  15. <div>
  16. <img :src="userInfo.avatar">
  17. </div>
  18. <div class="text">
  19. <div class="name">{{ userInfo.nickname }}</div>
  20. <div v-if="userInfo.level && userInfo.is_permanent" class="info">永久会员</div>
  21. <div v-else-if="userInfo.level && !userInfo.is_permanent && userInfo.surplus" class="info">您的会员剩余{{ userInfo.surplus }}天</div>
  22. <div v-else class="info">开通会员立享会员尊享权益</div>
  23. </div>
  24. <a v-if="userInfo.level" href="#flag">续费会员</a>
  25. <a v-else-if="!userInfo.is_permanent" href="#flag">开通会员</a>
  26. </div>
  27. <!-- 会员权益 -->
  28. <div v-if="interests.length" class="rights-section">
  29. <div class="title">
  30. <div class="inner">会员尊享权益</div>
  31. </div>
  32. <ul>
  33. <li v-for="item in interests" :key="item.id">
  34. <div class="image">
  35. <img :src="item.pic">
  36. </div>
  37. <div class="name">{{ item.name }}</div>
  38. <div class="info">{{ item.explain }}</div>
  39. </li>
  40. </ul>
  41. </div>
  42. <!-- 会员套餐 -->
  43. <div v-if="cardList.length" class="card-section" id="flag">
  44. <div class="title">
  45. <div class="inner">选择会员套餐</div>
  46. </div>
  47. <div class="radio-group">
  48. <label v-for="item in cardList" :key="item.id">
  49. <input v-model="cardChecked" :value="item" type="radio" hidden>
  50. <div>
  51. <div class="name">{{ item.title }}</div>
  52. <div class="money">¥<span>{{ item.price }}</span></div>
  53. <div class="delete">¥{{ item.original_price }}</div>
  54. </div>
  55. </label>
  56. </div>
  57. <button @click="loginUser(1)">{{ userInfo && userInfo.level ? '立即续费' : '立即开通' }}</button>
  58. <div v-if="userInfo && !userInfo.is_permanent" class="tip">已有卡密兑换会员,<a href="javascript:" @click="loginUser(2)">点击兑换</a></div>
  59. </div>
  60. <!-- 会员说明 -->
  61. <div v-if="description.length" class="detail-section">
  62. <div class="title">会员说明:</div>
  63. <ol>
  64. <li v-for="item in description" :key="item.id">{{ item.text }}</li>
  65. </ol>
  66. </div>
  67. <!-- 兑换弹窗 -->
  68. <div :class="{ mask: exchangeShow }" @click="exchangeShow = false"></div>
  69. <div :class="{ show: exchangeShow }" class="exchange-dialog">
  70. <button class="close" @click="exchangeShow = false">
  71. <i class="iconfont iconguanbi2"></i>
  72. </button>
  73. <div class="title">
  74. <div class="inner">激活会员卡</div>
  75. </div>
  76. <div class="content">
  77. <input v-model.trim="member_code" type="text" placeholder="请输入卡号">
  78. <input v-model.trim="member_pwd" type="password" placeholder="请输入卡密">
  79. </div>
  80. <div class="shade">
  81. <button @click="loginUser(3)">确认激活</button>
  82. </div>
  83. </div>
  84. <!-- 登陆弹窗 -->
  85. <base-login :login-show="loginShow" :site-name="siteName" @login-close="logComplete"></base-login>
  86. <!-- 支付弹窗 -->
  87. <pay-dialog :open.sync="payDialogOpen" :money="cardChecked && cardChecked.price" :special_id="cardChecked && cardChecked.id" :pay_type_num="pay_type_num" :is-wechat="isWechat" :is-alipay="isAlipay" :template-id="templateId" :wxpay-h5="wxpayH5" @change="changeVal"></pay-dialog>
  88. <quick-menu></quick-menu>
  89. <!-- 分享返佣 -->
  90. <rebate-guide v-if="rebateMoney && isShareDisplaySwitch" :rebate-money="rebateMoney" @rebate-action="rebateAction"></rebate-guide>
  91. </div>
  92. <script>
  93. require([
  94. 'vue',
  95. 'helper',
  96. 'store',
  97. 'components/pay-dialog/index',
  98. 'components/base-login/index',
  99. 'components/rebate-guide/index',
  100. 'quick',
  101. 'qrcode'
  102. ], function (Vue, $h, store, PayDialog, BaseLogin, RebateGuide) {
  103. var isAlipay = {$is_alipay},
  104. isWechat = '{$isWechat}',
  105. siteName = '{$Auth_site_name}',
  106. wxpayH5 = {$is_h5_wechat_payment_switch},
  107. callbackUrl = '{$callback_url}',
  108. spreadPosterUrl = '{$spread_poster_url}',
  109. url = '{$url}',
  110. app = new Vue({
  111. el: '#app',
  112. components: {
  113. 'pay-dialog': PayDialog,
  114. 'base-login': BaseLogin,
  115. 'rebate-guide': RebateGuide
  116. },
  117. data: {
  118. exchangeShow: false, // 是否显示兑换弹窗
  119. loginShow: false, // 是否显示登录弹窗
  120. userInfo: null, // 用户信息
  121. interests: [], // 会员权益
  122. description: [], // 会员说明
  123. cardList: [], // 会员套餐
  124. cardChecked: null, // 选中的套餐
  125. member_code: '', // 卡号
  126. member_pwd: '', // 卡密
  127. surplus: 0,
  128. siteName: siteName, // 站点名称
  129. isWechat: isWechat, // 是否是微信
  130. url: isWechat ? $h.U({ c: 'index', a: 'login' }) : $h.U({ c: 'login', a: 'phone_check' }),
  131. id: 0,
  132. payDialogOpen: false, // 是否显示支付弹窗
  133. isAlipay: isAlipay, // 是否开启支付宝支付
  134. pay_type_num: 10,
  135. templateId: '', // 订阅通知模板id
  136. wxpayH5: wxpayH5, // 是否开启微信H5支付
  137. rebateMoney: 0,
  138. isShareDisplaySwitch: {$is_share_display_switch} // 是否显示分享返佣
  139. },
  140. watch: {
  141. cardChecked: function (value) {
  142. if (value.is_free) {
  143. this.rebateMoney = 0;
  144. } else {
  145. this.rebateAmount();
  146. }
  147. }
  148. },
  149. created: function () {
  150. this.loginUser();
  151. if (isWechat) {
  152. this.mapleApi = mapleWx($jssdk());
  153. this.subscribe();
  154. }
  155. },
  156. methods: {
  157. // 订阅通知模板id
  158. subscribe: function () {
  159. var vm = this;
  160. store.baseGet($h.U({
  161. c: 'special',
  162. a: 'gettemplateIds',
  163. q: {
  164. pay_type_num: this.pay_type_num,
  165. special_id: this.cardChecked.id
  166. }
  167. }), function (res) {
  168. vm.templateId = res.data.msg;
  169. });
  170. },
  171. loginUser: function (type) {
  172. var vm = this;
  173. store.baseGet($h.U({
  174. c: 'index',
  175. a: 'login_user'
  176. }), function () {
  177. switch (type) {
  178. case 1:
  179. vm.payDialogOpen = true;
  180. break;
  181. case 2:
  182. vm.exchangeShow = true;
  183. break;
  184. case 3:
  185. vm.exchange();
  186. break;
  187. default:
  188. vm.getUserInfo();
  189. vm.getMemberList();
  190. vm.getMemberData();
  191. break;
  192. }
  193. }, function () {
  194. vm.loginShow = true;
  195. });
  196. },
  197. // 用户信息
  198. getUserInfo: function () {
  199. var vm = this;
  200. store.baseGet($h.U({
  201. c: 'auth_api',
  202. a: 'userInfo'
  203. }), function (res) {
  204. vm.userInfo = res.data.data;
  205. });
  206. },
  207. // 会员权益、说明
  208. getMemberData: function () {
  209. var vm = this;
  210. store.baseGet($h.U({
  211. c: 'auth_api',
  212. a: 'merberDatas'
  213. }), function (res) {
  214. var data = res.data.data;
  215. vm.interests = data.interests;
  216. vm.description = data.description;
  217. });
  218. },
  219. // 会员套餐
  220. getMemberList: function () {
  221. var vm = this;
  222. store.baseGet($h.U({
  223. c: 'auth_api',
  224. a: 'membershipLists'
  225. }), function (res) {
  226. var data = res.data.data;
  227. data.forEach(function (item) {
  228. item.price = Number(item.price);
  229. item.original_price = Number(item.original_price);
  230. });
  231. vm.cardList = data;
  232. vm.cardChecked = data[0] || null;
  233. });
  234. },
  235. pay_order: function (data) {
  236. this.orderId = data.data.result.orderId || '';
  237. switch (data.data.status) {
  238. case "PAY_ERROR": case 'ORDER_EXIST': case 'ORDER_ERROR':
  239. this.extendOrder(data.msg);
  240. break;
  241. case 'WECHAT_PAY':
  242. this.wechatPay(data.data.result.jsConfig);
  243. break;
  244. case 'WECHAT_H5_PAY':
  245. window.location.assign(data.data.result.jsConfig.mweb_url + '&redirect_url=' + encodeURIComponent(callbackUrl + '?type=5&id=0'));
  246. break;
  247. case 'ZHIFUBAO_PAY':
  248. window.location.assign($h.U({
  249. c: 'alipay',
  250. a: 'index',
  251. q: {
  252. info: data.data.result,
  253. params: 'member'
  254. }
  255. }));
  256. break;
  257. case 'SUCCESS':
  258. this.successOrder(data.msg);
  259. break;
  260. case 'ZHIFUBAO_PAY':
  261. window.location.href = $h.U({ m: 'wap', c: 'alipay', a: 'index', q: { info: data.data.result, params: 'member' } });
  262. break;
  263. }
  264. },
  265. wechatPay: function (config) {
  266. var vm = this;
  267. this.mapleApi.chooseWXPay(config, function () {
  268. vm.successOrder();
  269. }, {
  270. fail: vm.extendOrder,
  271. cancel: vm.extendOrder
  272. });
  273. },
  274. successOrder: function (msg) {
  275. var vm = this;
  276. $h.showMsg({
  277. title: msg ? msg : '领取成功',
  278. icon: 'success',
  279. success: function () {
  280. vm.payDialogOpen = false;
  281. vm.getUserInfo();
  282. vm.getMemberList();
  283. }
  284. });
  285. },
  286. extendOrder: function (msg) {
  287. var vm = this;
  288. if (typeof msg === 'object') {
  289. if (msg.errMsg === 'chooseWXPay:cancel') {
  290. msg = '微信支付取消';
  291. } else {
  292. msg = '支付失败';
  293. }
  294. } else {
  295. msg = '支付失败';
  296. }
  297. $h.pushMsg(msg, function () {
  298. that.payment = true;
  299. });
  300. },
  301. close: function () {
  302. this.popupShow = false
  303. },
  304. getUrlStr: function () {
  305. var queryStr = {};
  306. location.search.replace(/([^?&=]+)=([^&]+)/g, function (_, k, v) {
  307. queryStr[k] = v;
  308. });
  309. return queryStr;
  310. },
  311. // 激活
  312. exchange: function () {
  313. if (!this.member_code) {
  314. $h.pushMsg('请输入卡号');
  315. } else if (!this.member_pwd) {
  316. $h.pushMsg('请输入卡密');
  317. } else {
  318. $h.loadFFF();
  319. store.basePost($h.U({
  320. c: 'auth_api',
  321. a: 'confirm_activation'
  322. }), {
  323. member_code: this.member_code,
  324. member_pwd: this.member_pwd
  325. }, function (res) {
  326. $h.loadClear();
  327. $h.showMsg({
  328. title: res.data.msg,
  329. icon: 'success',
  330. success: function () {
  331. window.location.reload();
  332. }
  333. });
  334. }, function () {
  335. $h.loadClear();
  336. });
  337. }
  338. },
  339. enter: function () {
  340. this.loginShow = true;
  341. },
  342. payClose:function(value){
  343. this.payment=value;
  344. },
  345. //关闭登录
  346. loginClose: function (value) {
  347. this.loginShow = false;
  348. value && this.logComplete();
  349. },
  350. //登录完成回调事件
  351. logComplete: function () {
  352. this.loginShow = false;
  353. },
  354. //所有插件回调处理事件
  355. changeVal: function (opt) {
  356. if (typeof opt != 'object') opt = {};
  357. var action = opt.action || '';
  358. var value = opt.value || '';
  359. this[action] && this[action](value);
  360. },
  361. // 获取返佣金额
  362. rebateAmount: function () {
  363. var vm = this;
  364. store.baseGet($h.U({
  365. c: 'auth_api',
  366. a: 'rebateAmount',
  367. p: {
  368. type: 1,
  369. id: this.cardChecked.id
  370. }
  371. }), function (res) {
  372. vm.rebateMoney = parseFloat(res.data.data.brokeragePrice);
  373. });
  374. },
  375. // 生成分享海报
  376. createSharePoster: function () {
  377. var vm = this;
  378. var imagePromise = new Promise(function (resolve, reject) {
  379. var image = new Image();
  380. image.crossOrigin = 'anonymous';
  381. image.src = spreadPosterUrl + '?' + new Date().getTime();
  382. image.onload = function () {
  383. resolve(image);
  384. },
  385. image.onerror = function () {
  386. reject('error-image');
  387. };
  388. }),
  389. qrcodePromise = new Promise(function (resolve, reject) {
  390. resolve(new QRCode(document.createElement('canvas'), url));
  391. });
  392. Promise.all([
  393. imagePromise,
  394. qrcodePromise
  395. ]).then(function (sources) {
  396. var canvas = document.createElement('canvas');
  397. var context = canvas.getContext('2d');
  398. canvas.width = 600;
  399. canvas.height = 960;
  400. context.fillStyle = '#FFFFFF';
  401. context.fillRect(0, 0, 600, 960);
  402. context.drawImage(sources[0], 0, 0, 600, 740);
  403. context.drawImage(sources[1]._el.firstElementChild, 108, 775, 150, 150);
  404. context.font = '22px sans-serif';
  405. context.fillStyle = '#999999';
  406. context.textBaseline = 'top';
  407. var text = '邀您加入' + siteName;
  408. var list = [];
  409. var start = 0;
  410. for (var i = 0; i <= text.length; i++) {
  411. if (context.measureText(text.slice(start, i)).width > 198) {
  412. list.push(text.slice(start, i - 1));
  413. start = i - 1;
  414. }
  415. }
  416. if (start !== text.length) {
  417. list.push(text.slice(start));
  418. }
  419. if (list.length > 3) {
  420. list.length = 3;
  421. for (var j = 0; j <= list[2].length; j++) {
  422. if (context.measureText(list[2].slice(0, j) + '……').width > 198) {
  423. list[2] = list[2].slice(0, j - 1) + '……';
  424. break;
  425. }
  426. }
  427. }
  428. list.push('长按识别或扫码进入');
  429. for (var k = 0; k < list.length; k++) {
  430. context.fillText(list[k], 294, 775 + (150 / list.length) * k);
  431. }
  432. layer.photos({
  433. photos: {
  434. data: [
  435. {
  436. src: canvas.toDataURL('image/jpeg')
  437. }
  438. ]
  439. },
  440. anim: 5
  441. });
  442. canvas = null;
  443. }).catch(function (err) {
  444. $h.pushMsg(err);
  445. });
  446. },
  447. rebateAction: function (value) {
  448. switch (value) {
  449. case 'close':
  450. this.rebateMoney = 0;
  451. break;
  452. case 'share':
  453. this.createSharePoster();
  454. break;
  455. }
  456. }
  457. }
  458. });
  459. });
  460. </script>
  461. {/block}