C端小程序
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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