no message
Showing
16 changed files
with
868 additions
and
77 deletions
src/miniprogram_dist/index/index.js
0 → 100755
| 1 | const main = { | ||
| 2 | /** | ||
| 3 | * 渲染块 | ||
| 4 | * @param {Object} params | ||
| 5 | */ | ||
| 6 | drawBlock({ text, width = 0, height, x, y, paddingLeft = 0, paddingRight = 0, borderWidth, backgroundColor, borderColor, borderRadius = 0, opacity = 1 }) { | ||
| 7 | // 判断是否块内有文字 | ||
| 8 | let blockWidth = 0; // 块的宽度 | ||
| 9 | let textX = 0; | ||
| 10 | let textY = 0; | ||
| 11 | if (typeof text !== 'undefined') { | ||
| 12 | // 如果有文字并且块的宽度小于文字宽度,块的宽度为 文字的宽度 + 内边距 | ||
| 13 | const textWidth = this._getTextWidth(typeof text.text === 'string' ? text : text.text); | ||
| 14 | blockWidth = textWidth > width ? textWidth : width; | ||
| 15 | blockWidth += paddingLeft + paddingLeft; | ||
| 16 | |||
| 17 | const { textAlign = 'left', text: textCon } = text; | ||
| 18 | textY = height / 2 + y; // 文字的y轴坐标在块中线 | ||
| 19 | if (textAlign === 'left') { | ||
| 20 | // 如果是右对齐,那x轴在块的最左边 | ||
| 21 | textX = x + paddingLeft; | ||
| 22 | } else if (textAlign === 'center') { | ||
| 23 | textX = blockWidth / 2 + x; | ||
| 24 | } else { | ||
| 25 | textX = x + blockWidth - paddingRight; | ||
| 26 | } | ||
| 27 | } else { | ||
| 28 | blockWidth = width; | ||
| 29 | } | ||
| 30 | |||
| 31 | if (backgroundColor) { | ||
| 32 | // 画面 | ||
| 33 | this.ctx.save(); | ||
| 34 | this.ctx.setGlobalAlpha(opacity); | ||
| 35 | this.ctx.setFillStyle(backgroundColor); | ||
| 36 | if (borderRadius > 0) { | ||
| 37 | // 画圆角矩形 | ||
| 38 | this._drawRadiusRect(x, y, blockWidth, height, borderRadius); | ||
| 39 | this.ctx.fill(); | ||
| 40 | } else { | ||
| 41 | this.ctx.fillRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height)); | ||
| 42 | } | ||
| 43 | this.ctx.restore(); | ||
| 44 | } | ||
| 45 | if (borderWidth) { | ||
| 46 | // 画线 | ||
| 47 | this.ctx.save(); | ||
| 48 | this.ctx.setGlobalAlpha(opacity); | ||
| 49 | this.ctx.setStrokeStyle(borderColor); | ||
| 50 | this.ctx.setLineWidth(this.toPx(borderWidth)); | ||
| 51 | if (borderRadius > 0) { | ||
| 52 | // 画圆角矩形边框 | ||
| 53 | this._drawRadiusRect(x, y, blockWidth, height, borderRadius); | ||
| 54 | this.ctx.stroke(); | ||
| 55 | } else { | ||
| 56 | this.ctx.strokeRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height)); | ||
| 57 | } | ||
| 58 | this.ctx.restore(); | ||
| 59 | } | ||
| 60 | |||
| 61 | if (text) { | ||
| 62 | this.drawText(Object.assign(text, { x: textX, y: textY })) | ||
| 63 | } | ||
| 64 | }, | ||
| 65 | |||
| 66 | /** | ||
| 67 | * 渲染文字 | ||
| 68 | * @param {Object} params | ||
| 69 | */ | ||
| 70 | drawText(params) { | ||
| 71 | const { x, y, fontSize, color, baseLine, textAlign, text, opacity = 1, width, lineNum, lineHeight } = params; | ||
| 72 | if (Object.prototype.toString.call(text) === '[object Array]') { | ||
| 73 | let preText = { x, y, baseLine }; | ||
| 74 | text.forEach(item => { | ||
| 75 | preText.x += item.marginLeft || 0; | ||
| 76 | const textWidth = this._drawSingleText(Object.assign(item, { | ||
| 77 | ...preText, | ||
| 78 | })); | ||
| 79 | preText.x += textWidth + (item.marginRight || 0); // 下一段字的x轴为上一段字x + 上一段字宽度 | ||
| 80 | }) | ||
| 81 | } else { | ||
| 82 | this._drawSingleText(params); | ||
| 83 | } | ||
| 84 | }, | ||
| 85 | |||
| 86 | /** | ||
| 87 | * 渲染图片 | ||
| 88 | */ | ||
| 89 | drawImage(data) { | ||
| 90 | const { imgPath, x, y, w, h, sx, sy, sw, sh, borderRadius = 0, borderWidth = 0, borderColor } = data; | ||
| 91 | this.ctx.save(); | ||
| 92 | if (borderRadius > 0) { | ||
| 93 | this._drawRadiusRect(x, y, w, h, borderRadius); | ||
| 94 | this.ctx.strokeStyle = 'rgba(255,255,255,0)'; | ||
| 95 | this.ctx.stroke(); | ||
| 96 | this.ctx.clip(); | ||
| 97 | this.ctx.drawImage(imgPath, this.toPx(sx), this.toPx(sy), this.toPx(sw), this.toPx(sh), this.toPx(x), this.toPx(y), this.toPx(w), this.toPx(h)); | ||
| 98 | if (borderWidth > 0) { | ||
| 99 | this.ctx.setStrokeStyle(borderColor); | ||
| 100 | this.ctx.setLineWidth(this.toPx(borderWidth)); | ||
| 101 | this.ctx.stroke(); | ||
| 102 | } | ||
| 103 | } else { | ||
| 104 | this.ctx.drawImage(imgPath, this.toPx(sx), this.toPx(sy), this.toPx(sw), this.toPx(sh), this.toPx(x), this.toPx(y), this.toPx(w), this.toPx(h)); | ||
| 105 | } | ||
| 106 | this.ctx.restore(); | ||
| 107 | }, | ||
| 108 | /** | ||
| 109 | * 渲染线 | ||
| 110 | * @param {*} param0 | ||
| 111 | */ | ||
| 112 | drawLine({ startX, startY, endX, endY, color, width }) { | ||
| 113 | this.ctx.save(); | ||
| 114 | this.ctx.beginPath(); | ||
| 115 | this.ctx.setStrokeStyle(color); | ||
| 116 | this.ctx.setLineWidth(this.toPx(width)); | ||
| 117 | this.ctx.moveTo(this.toPx(startX), this.toPx(startY)); | ||
| 118 | this.ctx.lineTo(this.toPx(endX), this.toPx(endY)); | ||
| 119 | this.ctx.stroke(); | ||
| 120 | this.ctx.closePath(); | ||
| 121 | this.ctx.restore(); | ||
| 122 | }, | ||
| 123 | downloadResource(images = []) { | ||
| 124 | const drawList = []; | ||
| 125 | this.drawArr = []; | ||
| 126 | images.forEach((image, index) => drawList.push(this._downloadImageAndInfo(image, index))); | ||
| 127 | return Promise.all(drawList); | ||
| 128 | }, | ||
| 129 | initCanvas(w, h, debug) { | ||
| 130 | return new Promise((resolve) => { | ||
| 131 | this.setData({ | ||
| 132 | pxWidth: this.toPx(w), | ||
| 133 | pxHeight: this.toPx(h), | ||
| 134 | debug, | ||
| 135 | }, resolve); | ||
| 136 | }); | ||
| 137 | } | ||
| 138 | } | ||
| 139 | const handle = { | ||
| 140 | /** | ||
| 141 | * 画圆角矩形 | ||
| 142 | */ | ||
| 143 | _drawRadiusRect(x, y, w, h, r) { | ||
| 144 | const br = r / 2; | ||
| 145 | this.ctx.beginPath(); | ||
| 146 | this.ctx.moveTo(this.toPx(x + br), this.toPx(y)); // 移动到左上角的点 | ||
| 147 | this.ctx.lineTo(this.toPx(x + w - br), this.toPx(y)); | ||
| 148 | this.ctx.arc(this.toPx(x + w - br), this.toPx(y + br), this.toPx(br), 2 * Math.PI * (3 / 4), 2 * Math.PI * (4 / 4)) | ||
| 149 | this.ctx.lineTo(this.toPx(x + w), this.toPx(y + h - br)); | ||
| 150 | this.ctx.arc(this.toPx(x + w - br), this.toPx(y + h - br), this.toPx(br), 0, 2 * Math.PI * (1 / 4)) | ||
| 151 | this.ctx.lineTo(this.toPx(x + br), this.toPx(y + h)); | ||
| 152 | this.ctx.arc(this.toPx(x + br), this.toPx(y + h - br), this.toPx(br), 2 * Math.PI * (1 / 4), 2 * Math.PI * (2 / 4)) | ||
| 153 | this.ctx.lineTo(this.toPx(x), this.toPx(y + br)); | ||
| 154 | this.ctx.arc(this.toPx(x + br), this.toPx(y + br), this.toPx(br), 2 * Math.PI * (2 / 4), 2 * Math.PI * (3 / 4)) | ||
| 155 | }, | ||
| 156 | /** | ||
| 157 | * 计算文本长度 | ||
| 158 | * @param {Array|Object}} text 数组 或者 对象 | ||
| 159 | */ | ||
| 160 | _getTextWidth(text) { | ||
| 161 | let texts = []; | ||
| 162 | if (Object.prototype.toString.call(text) === '[object Object]') { | ||
| 163 | texts.push(text); | ||
| 164 | } else { | ||
| 165 | texts = text; | ||
| 166 | } | ||
| 167 | let width = 0; | ||
| 168 | texts.forEach(({ fontSize, text, marginLeft = 0, marginRight = 0 }) => { | ||
| 169 | this.ctx.setFontSize(this.toPx(fontSize)); | ||
| 170 | width += this.ctx.measureText(text).width + marginLeft + marginRight; | ||
| 171 | }) | ||
| 172 | |||
| 173 | return this.toRpx(width); | ||
| 174 | }, | ||
| 175 | /** | ||
| 176 | * 渲染一段文字 | ||
| 177 | */ | ||
| 178 | _drawSingleText({ x, y, fontSize, color, baseLine, textAlign = 'left', text, opacity = 1, textDecoration = 'none', | ||
| 179 | width, lineNum = 1, lineHeight = 0, fontWeight = 'normal', fontStyle = 'normal', fontFamily = "sans-serif"}) { | ||
| 180 | this.ctx.save(); | ||
| 181 | this.ctx.beginPath(); | ||
| 182 | this.ctx.font = fontStyle + " " + fontWeight + " " + this.toPx(fontSize, true) + "px " + fontFamily | ||
| 183 | this.ctx.setGlobalAlpha(opacity); | ||
| 184 | // this.ctx.setFontSize(this.toPx(fontSize)); | ||
| 185 | this.ctx.setFillStyle(color); | ||
| 186 | this.ctx.setTextBaseline(baseLine); | ||
| 187 | this.ctx.setTextAlign(textAlign); | ||
| 188 | let textWidth = this.toRpx(this.ctx.measureText(text).width); | ||
| 189 | const textArr = []; | ||
| 190 | if (textWidth > width) { | ||
| 191 | // 文本宽度 大于 渲染宽度 | ||
| 192 | let fillText = ''; | ||
| 193 | let line = 1; | ||
| 194 | for (let i = 0; i <= text.length - 1 ; i++) { // 将文字转为数组,一行文字一个元素 | ||
| 195 | fillText = fillText + text[i]; | ||
| 196 | if (this.toRpx(this.ctx.measureText(fillText).width) >= width) { | ||
| 197 | if (line === lineNum) { | ||
| 198 | if (i !== text.length - 1) { | ||
| 199 | fillText = fillText.substring(0, fillText.length - 1) + '...'; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | if(line <= lineNum) { | ||
| 203 | textArr.push(fillText); | ||
| 204 | } | ||
| 205 | fillText = ''; | ||
| 206 | line++; | ||
| 207 | } else { | ||
| 208 | if(line <= lineNum) { | ||
| 209 | if(i === text.length -1){ | ||
| 210 | textArr.push(fillText); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | } | ||
| 214 | } | ||
| 215 | textWidth = width; | ||
| 216 | } else { | ||
| 217 | textArr.push(text); | ||
| 218 | } | ||
| 219 | |||
| 220 | textArr.forEach((item, index) => { | ||
| 221 | this.ctx.fillText(item, this.toPx(x), this.toPx(y + (lineHeight || fontSize) * index)); | ||
| 222 | }) | ||
| 223 | |||
| 224 | this.ctx.restore(); | ||
| 225 | |||
| 226 | // textDecoration | ||
| 227 | if (textDecoration !== 'none') { | ||
| 228 | let lineY = y; | ||
| 229 | if (textDecoration === 'line-through') { | ||
| 230 | // 目前只支持贯穿线 | ||
| 231 | lineY = y; | ||
| 232 | } | ||
| 233 | this.ctx.save(); | ||
| 234 | this.ctx.moveTo(this.toPx(x), this.toPx(lineY)); | ||
| 235 | this.ctx.lineTo(this.toPx(x) + this.toPx(textWidth), this.toPx(lineY)); | ||
| 236 | this.ctx.setStrokeStyle(color); | ||
| 237 | this.ctx.stroke(); | ||
| 238 | this.ctx.restore(); | ||
| 239 | } | ||
| 240 | |||
| 241 | return textWidth; | ||
| 242 | }, | ||
| 243 | } | ||
| 244 | const helper = { | ||
| 245 | /** | ||
| 246 | * 下载图片并获取图片信息 | ||
| 247 | */ | ||
| 248 | _downloadImageAndInfo(image, index) { | ||
| 249 | return new Promise((resolve, reject) => { | ||
| 250 | const { x, y, url, zIndex } = image; | ||
| 251 | const imageUrl = url; | ||
| 252 | // 下载图片 | ||
| 253 | this._downImage(imageUrl, index) | ||
| 254 | // 获取图片信息 | ||
| 255 | .then(imgPath => this._getImageInfo(imgPath, index)) | ||
| 256 | .then(({ imgPath, imgInfo }) => { | ||
| 257 | // 根据画布的宽高计算出图片绘制的大小,这里会保证图片绘制不变形 | ||
| 258 | let sx; | ||
| 259 | let sy; | ||
| 260 | const borderRadius = image.borderRadius || 0; | ||
| 261 | const setWidth = image.width; | ||
| 262 | const setHeight = image.height; | ||
| 263 | const width = this.toRpx(imgInfo.width); | ||
| 264 | const height = this.toRpx(imgInfo.height); | ||
| 265 | |||
| 266 | if (width / height <= setWidth / setHeight) { | ||
| 267 | sx = 0; | ||
| 268 | sy = (height - ((width / setWidth) * setHeight)) / 2; | ||
| 269 | } else { | ||
| 270 | sy = 0; | ||
| 271 | sx = (width - ((height / setHeight) * setWidth)) / 2; | ||
| 272 | } | ||
| 273 | this.drawArr.push({ | ||
| 274 | type: 'image', | ||
| 275 | borderRadius, | ||
| 276 | borderWidth: image.borderWidth, | ||
| 277 | borderColor: image.borderColor, | ||
| 278 | zIndex: typeof zIndex !== 'undefined' ? zIndex : index, | ||
| 279 | imgPath, | ||
| 280 | sx, | ||
| 281 | sy, | ||
| 282 | sw: (width - (sx * 2)), | ||
| 283 | sh: (height - (sy * 2)), | ||
| 284 | x, | ||
| 285 | y, | ||
| 286 | w: setWidth, | ||
| 287 | h: setHeight, | ||
| 288 | }); | ||
| 289 | resolve(); | ||
| 290 | }) | ||
| 291 | .catch(err => reject(err)); | ||
| 292 | }); | ||
| 293 | }, | ||
| 294 | /** | ||
| 295 | * 下载图片资源 | ||
| 296 | * @param {*} imageUrl | ||
| 297 | */ | ||
| 298 | _downImage(imageUrl) { | ||
| 299 | return new Promise((resolve, reject) => { | ||
| 300 | if (/^http/.test(imageUrl) && !new RegExp(wx.env.USER_DATA_PATH).test(imageUrl)) { | ||
| 301 | wx.downloadFile({ | ||
| 302 | url: this._mapHttpToHttps(imageUrl), | ||
| 303 | success: (res) => { | ||
| 304 | if (res.statusCode === 200) { | ||
| 305 | resolve(res.tempFilePath); | ||
| 306 | } else { | ||
| 307 | reject(res.errMsg); | ||
| 308 | } | ||
| 309 | }, | ||
| 310 | fail(err) { | ||
| 311 | reject(err); | ||
| 312 | }, | ||
| 313 | }); | ||
| 314 | } else { | ||
| 315 | // 支持本地地址 | ||
| 316 | resolve(imageUrl); | ||
| 317 | } | ||
| 318 | }); | ||
| 319 | }, | ||
| 320 | /** | ||
| 321 | * 获取图片信息 | ||
| 322 | * @param {*} imgPath | ||
| 323 | * @param {*} index | ||
| 324 | */ | ||
| 325 | _getImageInfo(imgPath, index) { | ||
| 326 | return new Promise((resolve, reject) => { | ||
| 327 | wx.getImageInfo({ | ||
| 328 | src: imgPath, | ||
| 329 | success(res) { | ||
| 330 | resolve({ imgPath, imgInfo: res, index }); | ||
| 331 | }, | ||
| 332 | fail(err) { | ||
| 333 | reject(err); | ||
| 334 | }, | ||
| 335 | }); | ||
| 336 | }); | ||
| 337 | }, | ||
| 338 | toPx(rpx, int) { | ||
| 339 | if (int) { | ||
| 340 | return parseInt(rpx * this.factor); | ||
| 341 | } | ||
| 342 | return rpx * this.factor; | ||
| 343 | }, | ||
| 344 | toRpx(px, int) { | ||
| 345 | if (int) { | ||
| 346 | return parseInt(px / this.factor); | ||
| 347 | } | ||
| 348 | return px / this.factor; | ||
| 349 | }, | ||
| 350 | /** | ||
| 351 | * 将http转为https | ||
| 352 | * @param {String}} rawUrl 图片资源url | ||
| 353 | */ | ||
| 354 | _mapHttpToHttps(rawUrl) { | ||
| 355 | if (rawUrl.indexOf(':') < 0) { | ||
| 356 | return rawUrl; | ||
| 357 | } | ||
| 358 | const urlComponent = rawUrl.split(':'); | ||
| 359 | if (urlComponent.length === 2) { | ||
| 360 | if (urlComponent[0] === 'http') { | ||
| 361 | urlComponent[0] = 'https'; | ||
| 362 | return `${urlComponent[0]}:${urlComponent[1]}`; | ||
| 363 | } | ||
| 364 | } | ||
| 365 | return rawUrl; | ||
| 366 | }, | ||
| 367 | } | ||
| 368 | Component({ | ||
| 369 | properties: { | ||
| 370 | }, | ||
| 371 | created() { | ||
| 372 | const sysInfo = wx.getSystemInfoSync(); | ||
| 373 | const screenWidth = sysInfo.screenWidth; | ||
| 374 | this.factor = screenWidth / 750; | ||
| 375 | }, | ||
| 376 | methods: Object.assign({ | ||
| 377 | /** | ||
| 378 | * 计算画布的高度 | ||
| 379 | * @param {*} config | ||
| 380 | */ | ||
| 381 | getHeight(config) { | ||
| 382 | const getTextHeight = (text) => { | ||
| 383 | let fontHeight = text.lineHeight || text.fontSize; | ||
| 384 | let height = 0; | ||
| 385 | if (text.baseLine === 'top') { | ||
| 386 | height = fontHeight; | ||
| 387 | } else if (text.baseLine === 'middle') { | ||
| 388 | height = fontHeight / 2; | ||
| 389 | } else { | ||
| 390 | height = 0; | ||
| 391 | } | ||
| 392 | return height; | ||
| 393 | } | ||
| 394 | const heightArr = []; | ||
| 395 | (config.blocks || []).forEach((item) => { | ||
| 396 | heightArr.push(item.y + item.height); | ||
| 397 | }); | ||
| 398 | (config.texts || []).forEach((item) => { | ||
| 399 | let height; | ||
| 400 | if (Object.prototype.toString.call(item.text) === '[object Array]') { | ||
| 401 | item.text.forEach((i) => { | ||
| 402 | height = getTextHeight({...i, baseLine: item.baseLine}); | ||
| 403 | heightArr.push(item.y + height); | ||
| 404 | }); | ||
| 405 | } else { | ||
| 406 | height = getTextHeight(item); | ||
| 407 | heightArr.push(item.y + height); | ||
| 408 | } | ||
| 409 | }); | ||
| 410 | (config.images || []).forEach((item) => { | ||
| 411 | heightArr.push(item.y + item.height); | ||
| 412 | }); | ||
| 413 | (config.lines || []).forEach((item) => { | ||
| 414 | heightArr.push(item.startY); | ||
| 415 | heightArr.push(item.endY); | ||
| 416 | }); | ||
| 417 | const sortRes = heightArr.sort((a, b) => b - a); | ||
| 418 | let canvasHeight = 0; | ||
| 419 | if (sortRes.length > 0) { | ||
| 420 | canvasHeight = sortRes[0]; | ||
| 421 | } | ||
| 422 | if (config.height < canvasHeight || !config.height) { | ||
| 423 | return canvasHeight; | ||
| 424 | } else { | ||
| 425 | return config.height; | ||
| 426 | } | ||
| 427 | }, | ||
| 428 | create(config) { | ||
| 429 | this.ctx = wx.createCanvasContext('canvasid', this); | ||
| 430 | |||
| 431 | const height = this.getHeight(config); | ||
| 432 | this.initCanvas(config.width, height, config.debug) | ||
| 433 | .then(() => { | ||
| 434 | // 设置画布底色 | ||
| 435 | if (config.backgroundColor) { | ||
| 436 | this.ctx.save(); | ||
| 437 | this.ctx.setFillStyle(config.backgroundColor); | ||
| 438 | this.ctx.fillRect(0, 0, this.toPx(config.width), this.toPx(height)); | ||
| 439 | this.ctx.restore(); | ||
| 440 | } | ||
| 441 | const { texts = [], images = [], blocks = [], lines = [] } = config; | ||
| 442 | const queue = this.drawArr | ||
| 443 | .concat(texts.map((item) => { | ||
| 444 | item.type = 'text'; | ||
| 445 | item.zIndex = item.zIndex || 0; | ||
| 446 | return item; | ||
| 447 | })) | ||
| 448 | .concat(blocks.map((item) => { | ||
| 449 | item.type = 'block'; | ||
| 450 | item.zIndex = item.zIndex || 0; | ||
| 451 | return item; | ||
| 452 | })) | ||
| 453 | .concat(lines.map((item) => { | ||
| 454 | item.type = 'line'; | ||
| 455 | item.zIndex = item.zIndex || 0; | ||
| 456 | return item; | ||
| 457 | })); | ||
| 458 | // 按照顺序排序 | ||
| 459 | queue.sort((a, b) => a.zIndex - b.zIndex); | ||
| 460 | |||
| 461 | queue.forEach((item) => { | ||
| 462 | if (item.type === 'image') { | ||
| 463 | this.drawImage(item) | ||
| 464 | } else if (item.type === 'text') { | ||
| 465 | this.drawText(item) | ||
| 466 | } else if (item.type === 'block') { | ||
| 467 | this.drawBlock(item) | ||
| 468 | } else if (item.type === 'line') { | ||
| 469 | this.drawLine(item) | ||
| 470 | } | ||
| 471 | }); | ||
| 472 | |||
| 473 | const res = wx.getSystemInfoSync(); | ||
| 474 | const platform = res.platform; | ||
| 475 | let time = 0; | ||
| 476 | if (platform === 'android') { | ||
| 477 | // 在安卓平台,经测试发现如果海报过于复杂在转换时需要做延时,要不然样式会错乱 | ||
| 478 | time = 300; | ||
| 479 | } | ||
| 480 | this.ctx.draw(false, () => { | ||
| 481 | setTimeout(() => { | ||
| 482 | wx.canvasToTempFilePath({ | ||
| 483 | canvasId: 'canvasid', | ||
| 484 | success: (res) => { | ||
| 485 | this.triggerEvent('success', res.tempFilePath); | ||
| 486 | }, | ||
| 487 | fail: (err) => { | ||
| 488 | this.triggerEvent('fail', err); | ||
| 489 | }, | ||
| 490 | }, this); | ||
| 491 | }, time); | ||
| 492 | }); | ||
| 493 | }) | ||
| 494 | .catch((err) => { | ||
| 495 | wx.showToast({ icon: 'none', title: err.errMsg || '生成失败' }); | ||
| 496 | console.error(err); | ||
| 497 | }); | ||
| 498 | }, | ||
| 499 | }, main, handle, helper), | ||
| 500 | }); | ||
| 501 |
src/miniprogram_dist/index/index.json
0 → 100755
src/miniprogram_dist/index/index.wxml
0 → 100755
src/miniprogram_dist/index/index.wxss
0 → 100755
| 1 | .canvas { | ||
| 2 | width: 750rpx; | ||
| 3 | height: 750rpx; | ||
| 4 | } | ||
| 5 | .canvas.pro { | ||
| 6 | position: absolute; | ||
| 7 | bottom: 0; | ||
| 8 | left: 0; | ||
| 9 | transform: translate3d(-9999rpx, 0, 0); | ||
| 10 | } | ||
| 11 | .canvas.debug { | ||
| 12 | position: absolute; | ||
| 13 | bottom: 0; | ||
| 14 | left: 0; | ||
| 15 | border: 1rpx solid #ccc; | ||
| 16 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/miniprogram_dist/poster/index.js
0 → 100755
| 1 | Component({ | ||
| 2 | properties: { | ||
| 3 | config: { | ||
| 4 | type: Object, | ||
| 5 | value: {}, | ||
| 6 | }, | ||
| 7 | preload: { // 是否预下载图片资源 | ||
| 8 | type: Boolean, | ||
| 9 | value: false, | ||
| 10 | }, | ||
| 11 | hideLoading: { // 是否隐藏loading | ||
| 12 | type: Boolean, | ||
| 13 | value: false, | ||
| 14 | } | ||
| 15 | }, | ||
| 16 | ready() { | ||
| 17 | if (this.data.preload) { | ||
| 18 | const poster = this.selectComponent('#poster'); | ||
| 19 | this.downloadStatus = 'doing'; | ||
| 20 | poster.downloadResource(this.data.config.images).then(() => { | ||
| 21 | this.downloadStatus = 'success'; | ||
| 22 | this.trigger('downloadSuccess'); | ||
| 23 | }).catch((e) => { | ||
| 24 | this.downloadStatus = 'fail'; | ||
| 25 | this.trigger('downloadFail', e); | ||
| 26 | }); | ||
| 27 | } | ||
| 28 | }, | ||
| 29 | methods: { | ||
| 30 | trigger(event, data) { | ||
| 31 | if (this.listener && typeof this.listener[event] === 'function') { | ||
| 32 | this.listener[event](data); | ||
| 33 | } | ||
| 34 | }, | ||
| 35 | once(event, fun) { | ||
| 36 | if (typeof this.listener === 'undefined') { | ||
| 37 | this.listener = {}; | ||
| 38 | } | ||
| 39 | this.listener[event] = fun; | ||
| 40 | }, | ||
| 41 | downloadResource(reset) { | ||
| 42 | return new Promise((resolve, reject) => { | ||
| 43 | if (reset) { | ||
| 44 | this.downloadStatus = null; | ||
| 45 | } | ||
| 46 | const poster = this.selectComponent('#poster'); | ||
| 47 | if (this.downloadStatus && this.downloadStatus !== 'fail') { | ||
| 48 | if (this.downloadStatus === 'success') { | ||
| 49 | resolve(); | ||
| 50 | } else { | ||
| 51 | this.once('downloadSuccess', () => resolve()); | ||
| 52 | this.once('downloadFail', (e) => reject(e)); | ||
| 53 | } | ||
| 54 | } else { | ||
| 55 | poster.downloadResource(this.data.config.images) | ||
| 56 | .then(() => { | ||
| 57 | this.downloadStatus = 'success'; | ||
| 58 | resolve(); | ||
| 59 | }) | ||
| 60 | .catch((e) => reject(e)); | ||
| 61 | } | ||
| 62 | }) | ||
| 63 | }, | ||
| 64 | onCreate(reset = false) { | ||
| 65 | !this.data.hideLoading && wx.showLoading({ mask: true, title: '生成中' }); | ||
| 66 | return this.downloadResource(typeof reset === 'boolean' && reset).then(() => { | ||
| 67 | !this.data.hideLoading && wx.hideLoading(); | ||
| 68 | const poster = this.selectComponent('#poster'); | ||
| 69 | poster.create(this.data.config); | ||
| 70 | }) | ||
| 71 | .catch((err) => { | ||
| 72 | !this.data.hideLoading && wx.hideLoading(); | ||
| 73 | wx.showToast({ icon: 'none', title: err.errMsg || '生成失败' }); | ||
| 74 | console.error(err); | ||
| 75 | this.triggerEvent('fail', err); | ||
| 76 | }) | ||
| 77 | }, | ||
| 78 | onCreateSuccess(e) { | ||
| 79 | const { detail } = e; | ||
| 80 | this.triggerEvent('success', detail); | ||
| 81 | }, | ||
| 82 | onCreateFail(err) { | ||
| 83 | console.error(err); | ||
| 84 | this.triggerEvent('fail', err); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | }) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/miniprogram_dist/poster/index.json
0 → 100755
src/miniprogram_dist/poster/index.wxml
0 → 100755
src/miniprogram_dist/poster/index.wxss
0 → 100755
File mode changed
src/miniprogram_dist/poster/poster.js
0 → 100755
| 1 | const defaultOptions = { | ||
| 2 | selector: '#poster' | ||
| 3 | }; | ||
| 4 | |||
| 5 | function Poster(options = {}) { | ||
| 6 | options = { | ||
| 7 | ...defaultOptions, | ||
| 8 | ...options, | ||
| 9 | }; | ||
| 10 | |||
| 11 | const pages = getCurrentPages(); | ||
| 12 | const ctx = pages[pages.length - 1]; | ||
| 13 | |||
| 14 | const poster = ctx.selectComponent(options.selector); | ||
| 15 | delete options.selector; | ||
| 16 | |||
| 17 | return poster; | ||
| 18 | }; | ||
| 19 | |||
| 20 | Poster.create = (reset = false) => { | ||
| 21 | const poster = Poster(); | ||
| 22 | if (!poster) { | ||
| 23 | console.error('请设置组件的id="poster"!!!'); | ||
| 24 | } else { | ||
| 25 | return Poster().onCreate(reset); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | export default Poster; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -15,7 +15,7 @@ Page({ | ... | @@ -15,7 +15,7 @@ Page({ |
| 15 | name: "", | 15 | name: "", |
| 16 | phone: "", | 16 | phone: "", |
| 17 | messageContant: "", // 单词拼写错误 | 17 | messageContant: "", // 单词拼写错误 |
| 18 | 18 | userInfo: {}, | |
| 19 | 19 | ||
| 20 | }, | 20 | }, |
| 21 | onShareAppMessage() {}, | 21 | onShareAppMessage() {}, |
| ... | @@ -31,7 +31,31 @@ Page({ | ... | @@ -31,7 +31,31 @@ Page({ |
| 31 | // this.setData({ | 31 | // this.setData({ |
| 32 | // commonTipsCompVisible: false | 32 | // commonTipsCompVisible: false |
| 33 | // }) | 33 | // }) |
| 34 | this.queryMember().then((result) => { | ||
| 35 | this.setData({ | ||
| 36 | name:result.nickname | ||
| 37 | }) | ||
| 38 | }); | ||
| 34 | }, | 39 | }, |
| 40 | |||
| 41 | /** | ||
| 42 | * 获取会员信息 | ||
| 43 | */ | ||
| 44 | queryMember() { | ||
| 45 | return new Promise((resolve, reject) => { | ||
| 46 | app.post({ | ||
| 47 | url: app.api.member, | ||
| 48 | data: {} | ||
| 49 | }).then((result) => { | ||
| 50 | this.setData({ | ||
| 51 | userInfo: result | ||
| 52 | }) | ||
| 53 | resolve(result); | ||
| 54 | }) | ||
| 55 | }); | ||
| 56 | }, | ||
| 57 | |||
| 58 | |||
| 35 | /** | 59 | /** |
| 36 | * 提交表单 | 60 | * 提交表单 |
| 37 | */ | 61 | */ |
| ... | @@ -55,14 +79,14 @@ Page({ | ... | @@ -55,14 +79,14 @@ Page({ |
| 55 | }) | 79 | }) |
| 56 | return; | 80 | return; |
| 57 | } | 81 | } |
| 58 | if (!phone) { | 82 | // if (!phone) { |
| 59 | wx.showToast({ | 83 | // wx.showToast({ |
| 60 | title: "请输入联系方式", | 84 | // title: "请输入联系方式", |
| 61 | icon: 'none' | 85 | // icon: 'none' |
| 62 | }) | 86 | // }) |
| 63 | return; | 87 | // return; |
| 64 | } | 88 | // } |
| 65 | if (!checkMobile(phone)) { | 89 | if (phone && !checkMobile(phone)) { |
| 66 | wx.showToast({ | 90 | wx.showToast({ |
| 67 | title: "请输入正确联系方式", | 91 | title: "请输入正确联系方式", |
| 68 | icon: 'none' | 92 | icon: 'none' | ... | ... |
| ... | @@ -8,11 +8,11 @@ | ... | @@ -8,11 +8,11 @@ |
| 8 | <view class="form"> | 8 | <view class="form"> |
| 9 | <view class="form-item"> | 9 | <view class="form-item"> |
| 10 | <view class="label">用户姓名</view> | 10 | <view class="label">用户姓名</view> |
| 11 | <input class="val" bindinput="bindNameInput" placeholder="请输入姓名" /> | 11 | <input value="{{name}}" class="val" bindinput="bindNameInput" placeholder="请输入姓名" /> |
| 12 | </view> | 12 | </view> |
| 13 | <view class="form-item"> | 13 | <view class="form-item"> |
| 14 | <view class="label">联系方式</view> | 14 | <view class="label">联系方式</view> |
| 15 | <input class="val" bindinput="bindPhoneInput" placeholder="请输入联系方式" type="number" /> | 15 | <input class="val" bindinput="bindPhoneInput" placeholder="选填" type="number" /> |
| 16 | </view> | 16 | </view> |
| 17 | <textarea class="textarea" bindinput="bindMessageContantInput" maxlength="500" placeholder="不超过500字"></textarea> | 17 | <textarea class="textarea" bindinput="bindMessageContantInput" maxlength="500" placeholder="不超过500字"></textarea> |
| 18 | <!-- 图片上传 --> | 18 | <!-- 图片上传 --> | ... | ... |
| 1 | import QR from '../../utils/qrcode' | 1 | import QR from '../../utils/qrcode' |
| 2 | import Poster from '../../miniprogram_dist/poster/poster'; | ||
| 2 | 3 | ||
| 3 | let app = getApp(); | 4 | let app = getApp(); |
| 4 | Page({ | 5 | Page({ |
| ... | @@ -18,10 +19,115 @@ Page({ | ... | @@ -18,10 +19,115 @@ Page({ |
| 18 | this.initData(); | 19 | this.initData(); |
| 19 | }, | 20 | }, |
| 20 | initData() { | 21 | initData() { |
| 22 | // 获取用户信息 小程序码 | ||
| 21 | this.queryMember().then((result) => { | 23 | this.queryMember().then((result) => { |
| 24 | // 获取海报数据 | ||
| 25 | let posterData = this.getPosterConfig(); | ||
| 26 | // 绘制设置海报 | ||
| 27 | this.onCreatePoster(posterData); | ||
| 28 | }); | ||
| 29 | }, | ||
| 30 | |||
| 31 | onPosterSuccess(e) { | ||
| 32 | wx.hideLoading(); | ||
| 33 | const { | ||
| 34 | detail | ||
| 35 | } = e; | ||
| 36 | console.log("detail:", detail) | ||
| 37 | this.setData({ | ||
| 38 | imageUrl: detail | ||
| 39 | }) | ||
| 40 | }, | ||
| 41 | onPosterFail(err) { | ||
| 42 | wx.hideLoading(); | ||
| 43 | console.error(err); | ||
| 44 | }, | ||
| 22 | 45 | ||
| 46 | /** | ||
| 47 | * 异步生成海报 | ||
| 48 | */ | ||
| 49 | onCreatePoster(posterConfig) { | ||
| 50 | console.log("posterConfig:", posterConfig); | ||
| 51 | this.setData({ | ||
| 52 | posterConfig: posterConfig | ||
| 53 | }, () => { | ||
| 54 | Poster.create(true); // 入参:true为抹掉重新生成 | ||
| 23 | }); | 55 | }); |
| 24 | }, | 56 | }, |
| 57 | |||
| 58 | // 获取海报数据 | ||
| 59 | getPosterConfig() { | ||
| 60 | // 合成图片需要的数据 | ||
| 61 | let { | ||
| 62 | userInfo | ||
| 63 | } = this.data; | ||
| 64 | |||
| 65 | let blocks = [{ | ||
| 66 | x: 0, | ||
| 67 | y: 0, | ||
| 68 | width: 690, | ||
| 69 | height: 900, | ||
| 70 | backgroundColor: "#ffffff", | ||
| 71 | borderRadius: 10, | ||
| 72 | }]; | ||
| 73 | let images = [{ | ||
| 74 | x: 286, | ||
| 75 | y: 30, | ||
| 76 | width: 120, | ||
| 77 | height: 120, | ||
| 78 | borderRadius: 120, | ||
| 79 | zIndex: 11, | ||
| 80 | url: userInfo.avatar, | ||
| 81 | }, { | ||
| 82 | x: 126, | ||
| 83 | y: 220, | ||
| 84 | width: 440, | ||
| 85 | height: 440, | ||
| 86 | zIndex: 11, | ||
| 87 | url: userInfo.memberUrl, | ||
| 88 | }]; | ||
| 89 | let lines = []; | ||
| 90 | let texts = [{ | ||
| 91 | x: 690 / 2, | ||
| 92 | y: 192, | ||
| 93 | width: 690, | ||
| 94 | fontSize: 36, | ||
| 95 | color: "#3680EB", | ||
| 96 | textAlign: "center", | ||
| 97 | zIndex: 11, | ||
| 98 | text: userInfo.nickname, | ||
| 99 | }, { | ||
| 100 | x: 690 / 2, | ||
| 101 | y: 720, | ||
| 102 | width: 690, | ||
| 103 | fontSize: 28, | ||
| 104 | color: "#666666", | ||
| 105 | textAlign: "center", | ||
| 106 | zIndex: 11, | ||
| 107 | text: "深士照明", | ||
| 108 | }, { | ||
| 109 | x: 690 / 2, | ||
| 110 | y: 800, | ||
| 111 | width: 690, | ||
| 112 | fontSize: 28, | ||
| 113 | color: "#666666", | ||
| 114 | textAlign: "center", | ||
| 115 | zIndex: 11, | ||
| 116 | text: "扫码即获专属积分,兑换超值奖品", | ||
| 117 | }]; | ||
| 118 | |||
| 119 | let posterData = { | ||
| 120 | width: 690, | ||
| 121 | height: 900, | ||
| 122 | debug: false, | ||
| 123 | blocks: blocks, | ||
| 124 | images: images, | ||
| 125 | lines: lines, | ||
| 126 | texts: texts, | ||
| 127 | } | ||
| 128 | return posterData; | ||
| 129 | }, | ||
| 130 | |||
| 25 | /** | 131 | /** |
| 26 | * 获取会员信息 | 132 | * 获取会员信息 |
| 27 | */ | 133 | */ |
| ... | @@ -37,73 +143,15 @@ Page({ | ... | @@ -37,73 +143,15 @@ Page({ |
| 37 | userInfo: userInfo, | 143 | userInfo: userInfo, |
| 38 | qrImagePath: userInfo.memberUrl, | 144 | qrImagePath: userInfo.memberUrl, |
| 39 | }) | 145 | }) |
| 40 | |||
| 41 | wx.downloadFile({ | ||
| 42 | url: userInfo.memberUrl, | ||
| 43 | success(res) { | ||
| 44 | if (res.statusCode === 200) { | ||
| 45 | _this.setData({ | ||
| 46 | imageUrl: res.tempFilePath | ||
| 47 | }) | ||
| 48 | } | ||
| 49 | } | ||
| 50 | }) | ||
| 51 | |||
| 52 | // 生成个人二维码 | ||
| 53 | // let tlMemberCode = userInfo.memberCode; | ||
| 54 | // let qrSize = this.setCanvasSize(440); | ||
| 55 | // let codeContent = `tlMemberCode=${tlMemberCode}` | ||
| 56 | // this.createQrCode(codeContent, 'qrcanvas', qrSize.w, qrSize.h); | ||
| 57 | |||
| 58 | resolve(); | 146 | resolve(); |
| 59 | }) | 147 | }) |
| 60 | }); | 148 | }); |
| 61 | }, | 149 | }, |
| 62 | 150 | ||
| 63 | createQrCode(content, canvasId, cavW, cavH) { | ||
| 64 | //调用插件中的draw方法,绘制二维码图片 | ||
| 65 | QR.api.draw(content, canvasId, cavW, cavH); | ||
| 66 | this.canvasToTempImage(canvasId); | ||
| 67 | }, | ||
| 68 | //获取临时缓存图片路径,存入data中 | ||
| 69 | canvasToTempImage(canvasId) { | ||
| 70 | let that = this; | ||
| 71 | wx.canvasToTempFilePath({ | ||
| 72 | canvasId, // 这里canvasId即之前创建的canvas-id | ||
| 73 | success: function (res) { | ||
| 74 | let tempFilePath = res.tempFilePath; | ||
| 75 | console.log(tempFilePath); | ||
| 76 | that.setData({ // 如果采用mpvue,即 this.imagePath = tempFilePath | ||
| 77 | qrImagePath: tempFilePath, | ||
| 78 | }); | ||
| 79 | }, | ||
| 80 | fail: function (res) { | ||
| 81 | console.log(res); | ||
| 82 | } | ||
| 83 | }); | ||
| 84 | }, | ||
| 85 | //适配不同屏幕大小的canvas | ||
| 86 | setCanvasSize(sz) { | ||
| 87 | var size = {}; | ||
| 88 | try { | ||
| 89 | var res = wx.getSystemInfoSync(); | ||
| 90 | var scale = 750 / sz; //不同屏幕下canvas的适配比例;设计稿是750宽 | ||
| 91 | var width = res.windowWidth / scale; | ||
| 92 | var height = width; //canvas画布为正方形 | ||
| 93 | size.w = width; | ||
| 94 | size.h = height; | ||
| 95 | } catch (e) { | ||
| 96 | // Do something when catch error | ||
| 97 | console.log("获取设备信息失败" + e); | ||
| 98 | } | ||
| 99 | return size; | ||
| 100 | }, | ||
| 101 | |||
| 102 | /** | 151 | /** |
| 103 | * 保存图片到本地 | 152 | * 保存图片到本地 |
| 104 | */ | 153 | */ |
| 105 | saveImageToPhotosAlbum() { | 154 | saveImageToPhotosAlbum() { |
| 106 | console.log("saveImageToPhotosAlbum"); | ||
| 107 | let _this = this; | 155 | let _this = this; |
| 108 | if (!_this.data.imageUrl) { | 156 | if (!_this.data.imageUrl) { |
| 109 | wx.showToast({ | 157 | wx.showToast({ |
| ... | @@ -143,4 +191,52 @@ Page({ | ... | @@ -143,4 +191,52 @@ Page({ |
| 143 | } | 191 | } |
| 144 | }) | 192 | }) |
| 145 | }, | 193 | }, |
| 194 | |||
| 195 | |||
| 196 | |||
| 197 | |||
| 198 | |||
| 199 | |||
| 200 | |||
| 201 | // 创建二维码 | ||
| 202 | createQrCode(content, canvasId, cavW, cavH) { | ||
| 203 | //调用插件中的draw方法,绘制二维码图片 | ||
| 204 | QR.api.draw(content, canvasId, cavW, cavH); | ||
| 205 | this.canvasToTempImage(canvasId); | ||
| 206 | }, | ||
| 207 | //获取临时缓存图片路径,存入data中 | ||
| 208 | canvasToTempImage(canvasId) { | ||
| 209 | let that = this; | ||
| 210 | wx.canvasToTempFilePath({ | ||
| 211 | canvasId, // 这里canvasId即之前创建的canvas-id | ||
| 212 | success: function (res) { | ||
| 213 | let tempFilePath = res.tempFilePath; | ||
| 214 | console.log(tempFilePath); | ||
| 215 | that.setData({ // 如果采用mpvue,即 this.imagePath = tempFilePath | ||
| 216 | qrImagePath: tempFilePath, | ||
| 217 | }); | ||
| 218 | }, | ||
| 219 | fail: function (res) { | ||
| 220 | console.log(res); | ||
| 221 | } | ||
| 222 | }); | ||
| 223 | }, | ||
| 224 | //适配不同屏幕大小的canvas | ||
| 225 | setCanvasSize(sz) { | ||
| 226 | var size = {}; | ||
| 227 | try { | ||
| 228 | var res = wx.getSystemInfoSync(); | ||
| 229 | var scale = 750 / sz; //不同屏幕下canvas的适配比例;设计稿是750宽 | ||
| 230 | var width = res.windowWidth / scale; | ||
| 231 | var height = width; //canvas画布为正方形 | ||
| 232 | size.w = width; | ||
| 233 | size.h = height; | ||
| 234 | } catch (e) { | ||
| 235 | // Do something when catch error | ||
| 236 | console.log("获取设备信息失败" + e); | ||
| 237 | } | ||
| 238 | return size; | ||
| 239 | }, | ||
| 240 | |||
| 241 | |||
| 146 | }) | 242 | }) | ... | ... |
| ... | @@ -24,14 +24,19 @@ $contentWidth:690px; | ... | @@ -24,14 +24,19 @@ $contentWidth:690px; |
| 24 | 24 | ||
| 25 | .card { | 25 | .card { |
| 26 | margin: 0 auto; | 26 | margin: 0 auto; |
| 27 | padding: 20px 0 74px; | 27 | // padding: 20px 0 74px; |
| 28 | width: $contentWidth; | 28 | width: $contentWidth; |
| 29 | background: #FFFFFF; | 29 | // background: #FFFFFF; |
| 30 | box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.10); | 30 | // box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.10); |
| 31 | border-radius: 10px; | 31 | border-radius: 10px; |
| 32 | text-align: center; | 32 | text-align: center; |
| 33 | font-size: 32px; | 33 | font-size: 32px; |
| 34 | 34 | ||
| 35 | .my-card { | ||
| 36 | width: 690px; | ||
| 37 | height: 900px; | ||
| 38 | } | ||
| 39 | |||
| 35 | .avatar { | 40 | .avatar { |
| 36 | width: 120px; | 41 | width: 120px; |
| 37 | height: 120px; | 42 | height: 120px; | ... | ... |
| 1 | <poster id="poster" hide-loading="{{true}}" preload="{{false}}" config="{{posterConfig}}" bind:success="onPosterSuccess" bind:fail="onPosterFail"></poster> | ||
| 1 | <view class="page"> | 2 | <view class="page"> |
| 2 | <view class="app__bgc bgc"></view> | 3 | <view class="app__bgc bgc"></view> |
| 3 | <view class="app__bg bg"></view> | 4 | <view class="app__bg bg"></view> |
| ... | @@ -5,13 +6,12 @@ | ... | @@ -5,13 +6,12 @@ |
| 5 | <view class="top-space"></view> | 6 | <view class="top-space"></view> |
| 6 | <view class="content"> | 7 | <view class="content"> |
| 7 | <view class="card"> | 8 | <view class="card"> |
| 8 | <image class="avatar" mode="widthFix" src="{{userInfo.avatar}}" /> | 9 | <image class="my-card" mode="widthFix" src="{{imageUrl}}" /> |
| 10 | <!-- <image class="avatar" mode="widthFix" src="{{userInfo.avatar}}" /> | ||
| 9 | <view class="nickname">{{userInfo.nickname}}</view> | 11 | <view class="nickname">{{userInfo.nickname}}</view> |
| 10 | <image class="qrcode" mode="widthFix" src="{{qrImagePath}}" /> | 12 | <image class="qrcode" mode="widthFix" src="{{qrImagePath}}" /> |
| 11 | <!-- <image wx:if="{{qrImagePath}}" class="qrcode" mode="widthFix" src="{{qrImagePath}}" /> | ||
| 12 | <canvas wx:else class="qrcode" style="visibility: hidden;" canvas-id="qrcanvas" /> --> | ||
| 13 | <view class="t1">深士照明</view> | 13 | <view class="t1">深士照明</view> |
| 14 | <view class="t1 t2">扫码即获专属积分,兑换超值奖品</view> | 14 | <view class="t1 t2">扫码即获专属积分,兑换超值奖品</view> --> |
| 15 | </view> | 15 | </view> |
| 16 | <view class="tips">分享邀请好友加入,赢取推广积分</view> | 16 | <view class="tips">分享邀请好友加入,赢取推广积分</view> |
| 17 | <view class="btn-wrap"> | 17 | <view class="btn-wrap"> | ... | ... |
| ... | @@ -94,8 +94,21 @@ Page({ | ... | @@ -94,8 +94,21 @@ Page({ |
| 94 | parentId: "" | 94 | parentId: "" |
| 95 | } | 95 | } |
| 96 | }).then((result) => { | 96 | }).then((result) => { |
| 97 | let provinceList = result; | ||
| 98 | // ---- start 把广东移动到第一条 | ||
| 99 | for (var i = 0; i < provinceList.length; i++) { | ||
| 100 | let key = provinceList[i].areaName.indexOf('广东'); | ||
| 101 | if (key != -1) { | ||
| 102 | let target = provinceList[i]; | ||
| 103 | provinceList.unshift(target); | ||
| 104 | provinceList.splice(i + 1, 1); | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | // ---- end 把广东移动到第一条 | ||
| 109 | |||
| 97 | this.setData({ | 110 | this.setData({ |
| 98 | provinceList: result | 111 | provinceList: provinceList |
| 99 | }) | 112 | }) |
| 100 | console.log("provinceList:", result); | 113 | console.log("provinceList:", result); |
| 101 | }) | 114 | }) | ... | ... |
-
Please register or sign in to post a comment