C端小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

493 lines
15 KiB

  1. const Http = require("../../../../utils/HttpBasics");
  2. const imgurl = require("../../../../utils/imgurl");
  3. const config = require("../../../../config/config");
  4. const extConfig = wx.getExtConfigSync ? wx.getExtConfigSync() : {}
  5. let imgOrgUrl = extConfig.attr.imgOrgUrl;
  6. let imgOrgUrl1 = extConfig.attr.imgOrgUrl1;
  7. let imgNewUrl = extConfig.attr.imgNewUrl;
  8. let imgNewUrl1 = extConfig.attr.imgNewUrl;
  9. let app = getApp();
  10. Page({
  11. /**
  12. * 页面的初始数据
  13. */
  14. data: {
  15. poterbg: imgurl.poterbg.url,
  16. teljpgUrl: imgurl.teljpg.url,
  17. share01: imgurl.share01.url,
  18. actUrl: imgurl.act.url,
  19. poster: './../../../../assets/images/picture.png',
  20. page: 1,
  21. imglist: null,
  22. shopVoList: [],
  23. couponList: [], //活动劵列表
  24. qrCodeL: '', //小程序码
  25. currentTab: 0,
  26. isshare: false,
  27. showpost: false,
  28. imgHeight: 0,
  29. id: null,
  30. windowWidth: wx.getSystemInfoSync().windowWidth,
  31. windowHeight: wx.getSystemInfoSync().screenHeight,
  32. totalHeight: 0,
  33. canvasScale: 1.0, // 画布放大的倍数,因为如果保存的是一倍的分享图片的话,分享图会有点虚。所以保存的时候,canvasScale设置为2.0,wxss 里面的left: 500%;打开注释。就可保存两倍的分享图
  34. },
  35. //关闭海报
  36. closePoste: function() {
  37. this.setData({
  38. showpost: false
  39. })
  40. },
  41. /**
  42. * 生命周期函数--监听页面加载
  43. */
  44. onLoad: function(options) {
  45. let that = this;
  46. if (options && options.id) {
  47. this.setData({
  48. id: options.id
  49. });
  50. that.getList(options.id);
  51. that.getCouponList(options.id);
  52. this.setData({
  53. currentTab: 0
  54. })
  55. }
  56. this.getUserInfo()
  57. },
  58. /**
  59. * 绘制分享海报
  60. */
  61. begainDrawShareImage() {
  62. wx.showLoading({
  63. title: '生成中...',
  64. })
  65. var that = this
  66. // 适配屏幕
  67. let scale = this.data.windowWidth / 375.0
  68. this.setData({
  69. totalHeight: 767 * scale
  70. })
  71. // 获取Canvas
  72. let ctx = wx.createCanvasContext('myCanvas')
  73. // 获取宽高
  74. let wW = that.data.windowWidth;
  75. let wH = that.data.windowHeight;
  76. // 放大 因为不放大的话,生成的分享图会模糊。暂时先注释
  77. ctx.scale(this.data.canvasScale, this.data.canvasScale)
  78. // 绘制背景图
  79. let bgimg1 = this.data.poterbg + `?imageView/2/w/${wW}/h/${wH}`
  80. let bgimg2 = bgimg1.replace(imgOrgUrl1, imgNewUrl)
  81. ctx.drawImage(bgimg2, 0, 0, wW, wH);
  82. //绘制头像
  83. let avatar1 = this.data.avatarUrl + `?imageView/2/w/${wW}/h/${wH}`
  84. let avatar2 = avatar1.replace(imgOrgUrl, imgNewUrl)
  85. ctx.drawImage(avatar2, 15, 10, 30 * scale, 30 * scale);
  86. // 首先要绘制顶部的背景图片,因为它在最底层,然后才能绘制其他内容
  87. let topImageWidth = parseInt(315 * scale) // 因为小数有时候会请求不到图片,所以转成int
  88. let topImageHeight = parseInt(200 * scale)
  89. let src1 = this.data.data.merchantImgUrl + `?imageView/2/w/${topImageWidth}/h/${topImageHeight}`
  90. let src2 = src1.replace(imgOrgUrl, imgNewUrl)
  91. wx.getImageInfo({
  92. src: src2,
  93. success: function(res) {
  94. // 绘制白色背景
  95. ctx.setFillStyle('#fff')
  96. ctx.fillRect(25, 45, topImageWidth + 10, topImageHeight + 10)
  97. ctx.draw()
  98. ctx.drawImage(res.path, 30, 50, topImageWidth, topImageHeight)
  99. that.drawOtherContent(ctx, scale)
  100. that.drawOtherImage(ctx, scale)
  101. }
  102. })
  103. },
  104. //获取头像和昵称
  105. getUserInfo: function() {
  106. let that = this;
  107. // 获取用户信息
  108. Http.get({
  109. url: config.api.getScore,
  110. data: {}
  111. })
  112. .then(res => {
  113. console.log(res)
  114. that.setData({
  115. nickName: res.data.nickName,
  116. avatarUrl: res.data.avatarUrl
  117. })
  118. })
  119. },
  120. // 绘制除了图片之外的剩余内容
  121. drawOtherContent(ctx, scale) {
  122. //昵称
  123. this.drawNormalText(ctx, this.data.nickName + " 向您推荐", 50 * scale, 25 * scale, 16 * scale, '#fff', 'left', 'middle', scale);
  124. //店铺名
  125. this.drawNormalText(ctx, this.data.data.merchantName, 180 * scale, 280 * scale, 30 * scale, '#fff', 'center', 'middle', scale);
  126. //店铺电话
  127. // this.drawNormalText(ctx, "商铺电话:"+this.data.data.merchantLinkPhone, 100 * scale, 405 * scale, 16 * scale, '#000', 'left', 'middle', scale);
  128. if (this.data.couponList.length > 0) {
  129. for (let i = 0; i < this.data.couponList.length; i++) {
  130. // 第一个商品信息
  131. this.drawNormalText(ctx, this.substrTile(this.data.couponList[1].title), 40 * scale, 396 * scale, 14 * scale, '#000', 'left', 'middle', scale);
  132. this.drawNormalText(ctx, "价格:" + this.data.couponList[1].salePrice, 40 * scale, 416 * scale, 14 * scale, '#FF3232', 'left', 'middle', scale);
  133. //第二个商品信息
  134. this.drawNormalText(ctx, this.substrTile(this.data.couponList[2].title), 155 * scale, 396 * scale, 14 * scale, '#000', 'left', 'middle', scale);
  135. this.drawNormalText(ctx, "价格:" + this.data.couponList[2].salePrice, 155 * scale, 416 * scale, 14 * scale, '#FF3232', 'left', 'middle', scale);
  136. //第三个商品信息
  137. this.drawNormalText(ctx, this.substrTile(this.data.couponList[3].title), 270 * scale, 396 * scale, 14 * scale, '#000', 'left', 'middle', scale);
  138. this.drawNormalText(ctx, "价格:" + this.data.couponList[3].salePrice, 270 * scale, 416 * scale, 14 * scale, '#FF3232', 'left', 'middle', scale);
  139. }
  140. }
  141. this.drawNormalText(ctx, "长按二维码识别小程序进店逛逛", 85 * scale, 570 * scale, 16 * scale, '#000', 'left', 'middle', scale);
  142. ctx.draw(true)
  143. },
  144. //截取商品名
  145. substrTile(str) {
  146. return str.substr(0, 5) + '...'
  147. },
  148. // 绘制活动图片
  149. drawOtherImage(ctx, scale) {
  150. var that = this
  151. // 如果该商户有活动商品
  152. if (that.data.couponList.length > 0) {
  153. let cotentImageWidth = parseInt(80 * scale)
  154. let cotentImageHeight = parseInt(80 * scale)
  155. for (let i = 0; i < that.data.couponList.length; i++) {
  156. let imageItem = that.data.couponList[i].coverImg
  157. let src1 = imageItem + `?imageView/2/w/${cotentImageWidth}/h/${cotentImageHeight}`
  158. let src2 = src1.replace(imgOrgUrl, imgNewUrl)
  159. wx.getImageInfo({
  160. src: src2,
  161. success: function(res) {
  162. // ctx.setFillStyle('rgba(255,255,255,0.3)')
  163. // ctx.fillRect(25,300, 300*scale, 200*scale)
  164. // ctx.draw(true)
  165. ctx.drawImage(res.path, 45 * scale + i * 110 * scale, 300 * scale, cotentImageWidth, cotentImageHeight)
  166. }
  167. })
  168. }
  169. }
  170. if (this.data.qrCode) {
  171. let coImageWidth = parseInt(120 * scale)
  172. let coImageHeight = parseInt(120 * scale)
  173. let src1 = this.data.qrCode + `?imageView/2/w/${coImageWidth}/h/${coImageHeight}`
  174. let src2 = src1.replace(imgOrgUrl, imgNewUrl)
  175. wx.getImageInfo({
  176. src: src2,
  177. success: function(res) {
  178. ctx.drawImage(res.path, 115 * scale, 425 * scale, coImageWidth, coImageHeight)
  179. ctx.draw(true)
  180. }
  181. })
  182. }
  183. wx.hideLoading()
  184. },
  185. // 绘制只有一行的文字
  186. drawNormalText(ctx, str, x, y, font, style, align, baseLine) {
  187. ctx.setFontSize(font);
  188. ctx.setFillStyle(style);
  189. ctx.setTextAlign(align);
  190. ctx.setTextBaseline(baseLine);
  191. ctx.fillText(str, x, y);
  192. },
  193. /*
  194. * 绘制多行文本,自动换行,超出添加...
  195. *
  196. str:要绘制的字符串
  197. canvas:canvas对象
  198. initX:绘制字符串起始x坐标
  199. initY:绘制字符串起始y坐标
  200. lineHeight:字行高,自己定义个值即可
  201. maxWidth: 文本最大宽度
  202. row: 最大行数
  203. */
  204. canvasTextAutoLine: function(str, ctx, initX, initY, lineHeight, maxWidth, row = 1) {
  205. var lineWidth = 0;
  206. var lastSubStrIndex = 0;
  207. var currentRow = 1;
  208. for (let i = 0; i < str.length; i++) {
  209. lineWidth += ctx.measureText(str[i]).width;
  210. if (lineWidth > maxWidth) {
  211. currentRow++;
  212. let newStr = str.substring(lastSubStrIndex, i)
  213. if (currentRow > row && str.length > i) {
  214. newStr = str.substring(lastSubStrIndex, i - 2) + '...'
  215. }
  216. ctx.fillText(newStr, initX, initY);
  217. initY += lineHeight;
  218. lineWidth = 0;
  219. lastSubStrIndex = i;
  220. if (currentRow > row) {
  221. break;
  222. }
  223. }
  224. if (i == str.length - 1) {
  225. ctx.fillText(str.substring(lastSubStrIndex, i + 1), initX, initY);
  226. }
  227. }
  228. },
  229. /**
  230. * 图片预览方法
  231. * 此处注意的一点就是,调用 "wx.previewImage"时,第二个参数要求为数组形式哦
  232. * 当然,做过图片上传功能的应该会注意到,如果涉及到多张图片预览,图片链接数组集合即为参数 urls!
  233. */
  234. previewImage: function() {
  235. wx.canvasToTempFilePath({
  236. x: 0,
  237. y: 0,
  238. width: this.data.windowWidth * this.data.canvasScale,
  239. height: this.data.totalHeight * this.data.canvasScale,
  240. canvasId: 'myCanvas',
  241. success: function(res) {
  242. var current = res.tempFilePath;
  243. wx.previewImage({
  244. current: current,
  245. urls: [current]
  246. })
  247. },
  248. fail: function(res) {
  249. wx.showToast({
  250. title: '图片生成失败',
  251. icon: 'none',
  252. duration: 2000
  253. })
  254. }
  255. })
  256. },
  257. // 保存图片
  258. saveImage() {
  259. let that = this
  260. wx.canvasToTempFilePath({
  261. x: 0,
  262. y: 0,
  263. width: this.data.windowWidth * this.data.canvasScale,
  264. height: this.data.totalHeight * this.data.canvasScale,
  265. canvasId: 'myCanvas',
  266. success: function(res) {
  267. that.saveImageToPhotos(res.tempFilePath);
  268. },
  269. fail: function(res) {
  270. wx.showToast({
  271. title: '图片生成失败',
  272. icon: 'none',
  273. duration: 2000
  274. })
  275. }
  276. })
  277. },
  278. saveImageToPhotos: function(tempFilePath) {
  279. wx.saveImageToPhotosAlbum({
  280. filePath: tempFilePath,
  281. success(result) {
  282. wx.showToast({
  283. title: '保存成功,从相册中分享到朋友圈吧',
  284. icon: 'none',
  285. duration: 4000
  286. })
  287. },
  288. fail: function(err) {
  289. if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
  290. // 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
  291. wx.showModal({
  292. title: '提示',
  293. content: '需要您授权保存相册',
  294. showCancel: false,
  295. success: modalSuccess => {
  296. wx.openSetting({
  297. success(settingdata) {
  298. console.log("settingdata", settingdata)
  299. if (settingdata.authSetting['scope.writePhotosAlbum']) {
  300. wx.showModal({
  301. title: '提示',
  302. content: '获取权限成功,再次点击图片即可保存',
  303. showCancel: false,
  304. })
  305. } else {
  306. wx.showModal({
  307. title: '提示',
  308. content: '获取权限失败,将无法保存到相册哦~',
  309. showCancel: false,
  310. })
  311. }
  312. },
  313. fail(failData) {
  314. console.log("failData", failData)
  315. },
  316. complete(finishData) {
  317. console.log("finishData", finishData)
  318. }
  319. })
  320. }
  321. })
  322. }
  323. },
  324. })
  325. },
  326. /**
  327. * 拨打电话
  328. */
  329. phone: function(e) {
  330. let that = this;
  331. wx.makePhoneCall({
  332. phoneNumber: e.target.dataset.merchantlinkphone
  333. });
  334. },
  335. /**
  336. * 显示分享弹框
  337. */
  338. showshare: function() {
  339. this.setData({
  340. isshare: true,
  341. })
  342. },
  343. /**
  344. * 隐藏分享弹框
  345. */
  346. hidemodal: function() {
  347. this.setData({
  348. isshare: false,
  349. })
  350. },
  351. //滑动切换
  352. swiperTabView: function(e) {
  353. this.setData({
  354. currentTab: e.detail.current
  355. });
  356. },
  357. /**
  358. * 隐藏分享海报
  359. */
  360. hideposter: function() {
  361. this.setData({
  362. showpost: false,
  363. })
  364. },
  365. /**
  366. * 显示分享海报
  367. */
  368. showPoster: function() {
  369. this.setData({
  370. showpost: true,
  371. })
  372. this.begainDrawShareImage();
  373. },
  374. //点击切换
  375. clickTab: function(e) {
  376. if (this.data.currentTab === e.target.dataset.current) {
  377. return false;
  378. } else {
  379. this.setData({
  380. currentTab: e.target.dataset.current
  381. })
  382. }
  383. },
  384. /**
  385. * 获取商户详情
  386. */
  387. getList: function(id) {
  388. let that = this;
  389. let data;
  390. data = {
  391. pageNum: that.data.page,
  392. pageSize: 15,
  393. id: id
  394. }
  395. Http.get({
  396. url: config.api.merchantList,
  397. data: data
  398. }).then(res => {
  399. console.log(res)
  400. console.log("-----------------------------onShow---------------------------------------")
  401. let imgList = [];
  402. imgList.push(res.data.list[0].merchantImgUrl)
  403. that.setData({
  404. data: res.data.list[0],
  405. shopVoList: res.data.list[0].shopVoList,
  406. imglist: res.data.list[0].coverPicture == '[]' ? imgList : JSON.parse(res.data.list[0].coverPicture),
  407. })
  408. })
  409. .catch(err => {
  410. wx.showToast({
  411. title: err.errMsg,
  412. icon: 'none',
  413. duration: 2000,
  414. mask: false
  415. });
  416. })
  417. },
  418. /**
  419. * 获取商户活动信息 券类型(1.满减券,2.代金券,3.团购券,4.礼品券,5.停车券,6.多商户券,8.砍价券,9.团购券,50.积分券,51.积分停车券 100.消费卡)
  420. * 投放频道:(1.列表, 2.限时抢购, 3. banner图 4. 游戏 5.卡频道 6.砍价频道 7.拼团频道 8专题)
  421. */
  422. getCouponList: function(id) {
  423. let that = this;
  424. let data;
  425. data = {
  426. status: 0,
  427. merchantId: id,
  428. pageNum: that.data.page,
  429. pageSize: 15,
  430. }
  431. Http.get({
  432. url: config.api.listByMerchant,
  433. data: data
  434. }).then(res => {
  435. that.setData({
  436. couponList: res.data.page.list,
  437. qrCode: res.data.qrCode,
  438. })
  439. })
  440. .catch(err => {
  441. wx.showToast({
  442. title: err.errMsg,
  443. icon: 'none',
  444. duration: 2000,
  445. mask: false
  446. });
  447. })
  448. },
  449. /**
  450. * 获取多商铺列表
  451. */
  452. shopList: function(e) {
  453. wx.navigateTo({
  454. url: `/pages/index/merchantList/index?id=${e.currentTarget.dataset.id}`
  455. })
  456. },
  457. onShareAppMessage: function(res) {
  458. let that = this;
  459. let shareObj = {
  460. title: that.data.data.merchantName,
  461. path: `/pages/index/index?id=${that.data.id}&frommd=md`,
  462. success: function(res) {
  463. if (res.errMsg == 'shareAppMessage:ok') {}
  464. },
  465. fail: function(error) {
  466. if (res.errMsg == 'shareAppMessage:fail cancel') {} else if (res.errMsg == 'shareAppMessage:fail') {}
  467. }
  468. };
  469. // 来自页面内的按钮的转发
  470. if (res.from === 'button') {
  471. console.log(res)
  472. var eData = res.target.dataset.id;
  473. console.log(eData)
  474. shareObj.path = `/pages/index/index?id=${eData}&frommd=md`;
  475. }
  476. // 返回shareObj
  477. return shareObj;
  478. }
  479. })