From c00453f2731bdd509d38db58cb5c5951d28670f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9B=B9=E8=BE=89?= <814457906@qq.com>
Date: Fri, 3 Mar 2023 10:04:13 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
api/integral/index.js | 12 +-
components/r-canvas/r-canvas.js | 735 ++++++++++++++++++++++
components/r-canvas/r-canvas.vue | 26 +
package.json | 17 +-
pages.json | 14 +-
pages/CommodityOrder/CommodityOrder.vue | 42 +-
pages/Healthknowledge/Healthknowledge.vue | 13 +-
pages/Personal/Personal.vue | 12 +-
pages/homepage/homepage.vue | 10 +-
pages/integral/integral.vue | 631 ++++++++++++++++++-
10 files changed, 1442 insertions(+), 70 deletions(-)
create mode 100644 components/r-canvas/r-canvas.js
create mode 100644 components/r-canvas/r-canvas.vue
diff --git a/api/integral/index.js b/api/integral/index.js
index f341f0a..206c1d3 100644
--- a/api/integral/index.js
+++ b/api/integral/index.js
@@ -18,10 +18,18 @@ export function selectPatientSignIn(patientId) {
}
//可兑换商品
-
-export function selectExchangeGoods(pageNum,pageSize) {
+export function selectExchangeGoods(pageNum, pageSize) {
return request({
url: `/nurseApplet/patientInfo/selectExchangeGoods?pageNum=${pageNum}&pageSize=${pageSize}`,
method: 'get'
})
}
+
+//兑换
+export function integralGoodsOrder(data) {
+ return request({
+ url: `/nurseApplet/patientInfo/integralGoodsOrder`,
+ method: 'post',
+ data
+ })
+}
diff --git a/components/r-canvas/r-canvas.js b/components/r-canvas/r-canvas.js
new file mode 100644
index 0000000..256a23d
--- /dev/null
+++ b/components/r-canvas/r-canvas.js
@@ -0,0 +1,735 @@
+export default{
+ data(){
+ return{
+ system_info:{}, //system info
+ canvas_width:0, //canvas width px
+ canvas_height:0, //canvas height px
+ ctx:null, //canvas object
+ canvas_id:null, //canvas id
+ hidden:false,//Whether to hide canvas
+ scale:1,//canvas scale
+ r_canvas_scale:1,
+ if_ctx:true
+ }
+ },
+ methods:{
+ /**
+ * save r-canvas.vue object
+ * @param {Object} that
+ */
+ // saveThis(that){
+ // rCanvasThis = that
+ // },
+ /**
+ * Draw round rect text
+ * @param {Object} config
+ * @param {Number} config.x x坐标
+ * @param {Number} config.y y坐标
+ * @param {Number} config.w 宽度
+ * @param {Number} config.h 高度
+ * @param {Number} config.radius 圆角弧度
+ * @param {String} config.fill_color 矩形颜色
+ */
+ fillRoundRect(config) {
+ return new Promise((resolve,reject)=>{
+ let x = this.compatibilitySize(parseFloat(config.x)*this.scale)
+ let y = this.compatibilitySize(parseFloat(config.y)*this.scale)
+ let w = this.compatibilitySize(parseFloat(config.w)*this.scale)
+ let h = this.compatibilitySize(parseFloat(config.h)*this.scale)
+ let radius = config.radius?parseFloat(config.radius)*this.scale:10*this.scale
+
+ let fill_color = config.fill_color || "black"
+ // The diameter of the circle must be less than the width and height of the rectangle
+ if (2 * radius > w || 2 * radius > h) {
+ reject("The diameter of the circle must be less than the width and height of the rectangle")
+ return false;
+ }
+ this.ctx.save();
+ this.ctx.translate(x, y);
+ //
+ this.drawRoundRectPath({
+ w: w,
+ h: h,
+ radius: radius
+ });
+ this.ctx.fillStyle = fill_color
+ this.ctx.fill();
+ this.ctx.restore();
+ resolve()
+ })
+ },
+ /**
+ * Draws the sides of a rounded rectangle
+ * @param {Object} config
+ * @param {Number} config.w 宽度
+ * @param {Number} config.h 高度
+ * @param {Number} config.radius 圆角弧度
+ */
+ drawRoundRectPath(config) {
+ this.ctx.beginPath(0);
+ this.ctx.arc(config.w - config.radius, config.h - config.radius, config.radius, 0, Math.PI / 2);
+ this.ctx.lineTo(config.radius, config.h);
+ this.ctx.arc(config.radius, config.h - config.radius, config.radius, Math.PI / 2, Math.PI);
+ this.ctx.lineTo(0, config.radius);
+ this.ctx.arc(config.radius, config.radius, config.radius, Math.PI, Math.PI * 3 / 2);
+ this.ctx.lineTo(config.w - config.radius, 0);
+ this.ctx.arc(config.w - config.radius, config.radius, config.radius, Math.PI * 3 / 2, Math.PI * 2);
+ this.ctx.lineTo(config.w, config.h - config.radius);
+ this.ctx.closePath();
+ },
+ /**
+ * Draw special Text,line wrapping is not supported
+ * @param {Object} config
+ * @param {String} config.text 文字
+ * @param {Number} config.x x坐标
+ * @param {Number} config.y y坐标
+ * @param {String} config.font_color 文字颜色
+ * @param {String} config.font_family 文字字体
+ * @param {Number} config.font_size 文字大小(px)
+ */
+ drawSpecialText(params){
+ let general = params.general
+ let list = params.list
+ return new Promise(async (resolve,reject)=>{
+ if(!general){
+ reject("general cannot be empty:101")
+ return;
+ }else if(list && list.length>0){
+ for(let i in list){
+ if(i != 0){
+ let font_size = list[i-1].font_size?parseFloat(list[i-1].font_size):20
+ this.ctx.setFontSize(font_size)
+ general.x = parseFloat(general.x) + this.ctx.measureText(list[i-1].text).width
+ }
+ list[i].x = general.x
+ list[i].y = general.y + (list[i].margin_top?parseFloat(list[i].margin_top):0)
+ await this.drawText(list[i])
+ }
+ resolve()
+ }else{
+ reject("The length of config arr is less than 0")
+ return;
+ }
+
+ })
+ },
+ /**
+ * array delete empty
+ * @param {Object} arr
+ */
+ arrDeleteEmpty(arr){
+ let newArr = []
+ for(let i in arr){
+ if(arr[i]){
+ newArr.push(arr[i])
+ }
+ }
+ return newArr
+ },
+ /**
+ * Draw Text,support line
+ * @param {Object} config
+ * @param {String} config.text 文字
+ * @param {Number} config.max_width 文字最大宽度(大于宽度自动换行)
+ * @param {Number} config.line_height 文字上下行间距
+ * @param {Number} config.x x坐标
+ * @param {Number} config.y y坐标
+ * @param {String} config.font_color 文字颜色
+ * @param {String} config.font_family 文字字体 默认值:Arial
+ * @param {String} config.text_align 文字对齐方式(left/center/right)
+ * @param {Number} config.font_size 文字大小(px)
+ * @param {Boolean} config.line_through_height 中划线大小
+ * @param {Boolean} config.line_through_color 中划线颜色
+ * @param {String} config.font_style 规定文字样式
+ * @param {String} config.font_variant 规定字体变体
+ * @param {String} config.font_weight 规定字体粗细
+ * @param {String} config.line_through_cap 线末端类型
+ * @param {String} config.line_clamp 最大行数
+ * @param {String} config.line_clamp_hint 超过line_clamp后,尾部显示的自定义标识 如 ...
+ * @param {String} config.is_line_break 是否开启换行符换行
+ *
+ */
+ drawText(config,configuration = {}){
+
+ configuration['line_num'] = configuration.line_num?configuration.line_num:0
+ configuration['text_width'] = configuration.text_width?configuration.text_width:0
+
+ return new Promise(async (resolve,reject)=>{
+
+ if(config.text){
+
+ let draw_width = 0,draw_height = 0,draw_x = config.x,draw_y = config.y
+ let font_size = config.font_size?(parseFloat(config.font_size)*this.scale):(20*this.scale)
+ let font_color = config.font_color || "#000"
+ let font_family = config.font_family || "Arial"
+ let line_height = config.line_height || config.font_size || 20
+ let text_align = config.text_align || "left"
+ let font_weight = config.font_weight || "normal"
+ let font_variant = config.font_variant || "normal"
+ let font_style = config.font_style || "normal"
+ let line_clamp_hint = config.line_clamp_hint || '...'
+ let lineBreakJoinText = ""
+ let max_width = config.max_width?parseFloat(config.max_width)*this.scale:0
+ // checkout is line break
+ if(config.is_line_break){
+ let splitTextArr = config.text.split(/[\n]/g)
+ if(splitTextArr && splitTextArr.length > 0){
+ let newSplitTextArr = this.arrDeleteEmpty(splitTextArr)
+ if(newSplitTextArr && newSplitTextArr.length > 0){
+ lineBreakJoinText = newSplitTextArr.slice(1).join("\n")
+ config.text = newSplitTextArr[0]
+ }else{
+ reject("Text cannot be empty:103")
+ return
+ }
+ }else{
+ reject("Text cannot be empty:102")
+ return
+ }
+ }
+
+ this.ctx.setFillStyle(font_color) // color
+ this.ctx.textAlign = text_align;
+ this.ctx.font = `${font_style} ${font_variant} ${font_weight} ${parseInt(font_size)}px ${font_family}`
+ if(configuration.text_width >= this.ctx.measureText(config.text).width){
+ draw_width = configuration.text_width
+ }else if(max_width > 0){
+ draw_width = max_width < this.ctx.measureText(config.text).width ? this.resetCompatibilitySize(max_width) : this.resetCompatibilitySize(this.ctx.measureText(config.text).width)
+ }else{
+ draw_width = this.ctx.measureText(config.text).width
+ }
+ configuration.text_width = draw_width / this.scale
+ if( max_width && this.compatibilitySize(this.ctx.measureText(config.text).width) > this.compatibilitySize(max_width)){
+ let current_text = ""
+ let text_arr = config.text.split("")
+ for(let i in text_arr){
+ if( this.compatibilitySize(this.ctx.measureText(current_text+text_arr[i]).width) > this.compatibilitySize(max_width) ){
+ // Hyphenation that is greater than the drawable width continues to draw
+ if(config.line_clamp && parseInt(config.line_clamp) == 1){
+ // Subtracting the current_text tail width from the line_clamp_hint width
+ let current_text_arr = current_text.split('')
+ let json_current_text = ''
+ while(true){
+ current_text_arr = current_text_arr.slice(1)
+ json_current_text = current_text_arr.join('')
+ if(this.compatibilitySize(this.ctx.measureText(json_current_text).width) <= this.compatibilitySize(this.ctx.measureText(line_clamp_hint).width)){
+ current_text = current_text.replace(json_current_text,'')
+ break;
+ }
+ }
+ configuration.line_num += 1
+ this.ctx.setFontSize(parseInt(this.compatibilitySize(font_size))) // font size
+ this.ctx.fillText(current_text + line_clamp_hint, this.compatibilitySize(parseFloat(config.x)*this.scale), this.compatibilitySize(parseFloat(config.y)*this.scale));
+ }else{
+ configuration.line_num += 1
+ this.ctx.setFontSize(parseInt(this.compatibilitySize(font_size))) // font size
+ this.ctx.fillText(current_text, this.compatibilitySize(parseFloat(config.x)*this.scale), this.compatibilitySize(parseFloat(config.y)*this.scale));
+ config.text = text_arr.slice(i).join("")
+ config.y = config.y + line_height
+ if(config.line_clamp){
+ config.line_clamp = parseInt(config.line_clamp) - 1
+ }
+ await this.drawText(config,configuration)
+ }
+
+ break;
+ }else{
+ current_text = current_text+text_arr[i]
+ }
+ }
+ }else{
+ if(config.line_through_height){
+ let x = parseFloat(config.x)*this.scale
+ let w
+ let y = parseFloat(config.y)*this.scale - (font_size / 2.6)
+ if(text_align == "left"){
+ w = this.ctx.measureText(config.text).width/1.1 + parseFloat(config.x)*this.scale
+ }else if(text_align == "right"){
+ w = parseFloat(config.x)*this.scale - this.ctx.measureText(config.text).width/1.1
+ }else if(text_align == "center"){
+ x = parseFloat(config.x)*this.scale - this.ctx.measureText(config.text).width / 1.1 / 2
+ w = parseFloat(config.x)*this.scale + this.ctx.measureText(config.text).width / 1.1 / 2
+ }
+ this.drawLineTo({
+ x:x,
+ y:y,
+ w:w,
+ h:y,
+ line_width:config.line_through_height,
+ line_color:config.line_through_color,
+ line_cap:config.line_through_cap
+ })
+ }
+ configuration.line_num += 1
+ this.ctx.setFontSize(parseInt(this.compatibilitySize(font_size))) // font size
+ this.ctx.fillText(config.text, this.compatibilitySize(parseFloat(config.x)*this.scale), this.compatibilitySize(parseFloat(config.y)*this.scale));
+ if(config.line_clamp){
+ config.line_clamp = parseInt(config.line_clamp) - 1
+ }
+ }
+ if(lineBreakJoinText){
+ await this.drawText({...config,text:lineBreakJoinText,y:config.y + line_height},configuration)
+ }
+ draw_height = config.font_size * configuration.line_num
+ draw_width = configuration.text_width
+ resolve({draw_width,draw_height,draw_x,draw_y})
+ }else{
+ reject("Text cannot be empty:101")
+ }
+ })
+ },
+ /**
+ * Draw Line
+ * @param {Object} config
+ * @param {Object} config.x x坐标
+ * @param {Object} config.y y坐标
+ * @param {Object} config.w 线的宽度
+ * @param {Object} config.h 线的高度
+ * @param {Object} config.line_width 线的宽度
+ * @param {Object} config.line_color 线条颜色
+ */
+ drawLineTo(config){
+ let x = this.compatibilitySize(config.x)
+ let y = this.compatibilitySize(config.y)
+ let w = this.compatibilitySize(config.w)
+ let h = this.compatibilitySize(config.h)
+ let line_width = config.line_width?parseFloat(config.line_width)*this.scale:1*this.scale
+ let line_color = config.line_color || "black"
+ let line_cap = config.line_cap || "butt"
+ this.ctx.beginPath()
+ this.ctx.lineCap = line_cap
+ this.ctx.lineWidth = line_width
+ this.ctx.strokeStyle = line_color
+ this.ctx.moveTo(x,y)
+ this.ctx.lineTo(w,h)
+ this.ctx.stroke()
+ },
+ /**
+ * Compatibility px
+ * @param {Object} size
+ */
+ compatibilitySize(size) {
+ let canvasSize = (parseFloat(size) / 750) * this.system_info.windowWidth
+ canvasSize = parseFloat(canvasSize * 2)
+ return canvasSize
+ },
+ /**
+ * Restore compatibility px
+ * @param {Object} size
+ */
+ resetCompatibilitySize(size) {
+ let canvasSize = (parseFloat(size/2)/this.system_info.windowWidth) * 750
+ return canvasSize
+ },
+ /**
+ * Init canvas
+ */
+ init(config){
+ return new Promise(async (resolve,reject)=>{
+ if(!config.canvas_id){
+ reject("Canvas ID cannot be empty, please refer to the usage example")
+ return;
+ }
+ this.hidden = config.hidden
+ this.canvas_id = config.canvas_id
+ let system_info = await uni.getSystemInfoSync()
+ this.system_info = system_info
+ this.scale = config.scale&&parseFloat(config.scale)>0?parseInt(config.scale):1
+ this.canvas_width = (config.canvas_width ? this.compatibilitySize(config.canvas_width) : system_info.windowWidth) * this.scale
+ this.canvas_height = (config.canvas_height ? this.compatibilitySize(config.canvas_height) : system_info.windowHeight) * this.scale,
+ this.r_canvas_scale = 1/this.scale
+ this.ctx = uni.createCanvasContext(this.canvas_id,this)
+ this.setCanvasConfig({
+ global_alpha:config.global_alpha?parseFloat(config.global_alpha):1,
+ backgroundColor:config.background_color?config.background_color:"#fff"
+ })
+ resolve()
+ })
+ },
+ /**
+ * clear canvas all path
+ */
+ clearCanvas(){
+ return new Promise(async (resolve,reject)=>{
+ if(!this.ctx){
+ reject("canvas is not initialized:101")
+ return
+ }else{
+ this.ctx.clearRect(0,0,parseFloat(this.canvas_width)*this.scale,parseFloat(this.canvas_height)*this.scale)
+ await this.draw()
+ resolve()
+ }
+ })
+ },
+ /**
+ * Set canvas config
+ * @param {Object} config
+ */
+ setCanvasConfig(config){
+ this.ctx.globalAlpha = config.global_alpha
+ this.ctx.fillStyle = config.backgroundColor
+ this.ctx.fillRect(0, 0, parseFloat(this.canvas_width)*this.scale, parseFloat(this.canvas_height)*this.scale)
+ },
+ /**
+ * set canvas width
+ * @param {Object} width
+ */
+ setCanvasWidth(width){
+ if(!width){
+ // uni.showToast({
+ // title:'setCanvasWidth:width error',
+ // icon:'none'
+ // })
+ }
+ this.canvas_width = this.compatibilitySize(parseFloat(width)) * this.scale
+ this.ctx.width = this.canvas_width
+ },
+ /**
+ * set canvas height
+ * @param {Object} height
+ */
+ setCanvasHeight(height){
+ if(!height){
+ // uni.showToast({
+ // title:'setCanvasWidth:height error',
+ // icon:'none'
+ // })
+ }
+ this.canvas_height = this.compatibilitySize(parseFloat(height)) * this.scale
+ this.ctx.height = this.canvas_height
+ },
+ /**
+ * Draw to filepath
+ */
+ draw(callback){
+ return new Promise((resolve,reject)=>{
+ let stop = setTimeout(()=>{
+ this.ctx.draw(false,setTimeout(()=>{
+ uni.canvasToTempFilePath({
+ canvasId: this.canvas_id,
+ quality: 1,
+ success: (res)=>{
+ console.log('res',res)
+ resolve(res)
+ callback && callback(res)
+ },
+ fail:(err)=>{
+ reject(JSON.stringify(err)|| "Failed to generate poster:101")
+ }
+ },this)
+ },300))
+ clearTimeout(stop)
+ },300)
+ })
+ },
+ /**
+ * draw rect
+ * @param {Number} config.x x坐标
+ * @param {Number} config.y y坐标
+ * @param {Number} config.w 图形宽度(px)
+ * @param {Number} config.h 图形高度(px)
+ * @param {Number} config.color 图形颜色
+ * @param {Number} config.is_radius 是否开启圆图(1.1.6及以下版本废弃,请使用border_radius)
+ * @param {Number} config.border_width 边框大小
+ * @param {Number} config.border_color 边框颜色
+ *
+ */
+ drawRect(config){
+ return new Promise(async (resolve,reject)=>{
+ if(!config.border_width || config.border_width <=0){
+ config.border_width = 0
+ }else{
+ config.border_width = parseFloat(config.border_width)
+ }
+ if(parseFloat(config.border_width) > 0){
+ let sub_config = JSON.parse(JSON.stringify(config))
+ sub_config.border_width = 0
+ sub_config.w = config.w + config.border_width
+ sub_config.h = config.h + config.border_width
+ sub_config.color = config.border_color || 'black'
+ if(sub_config.border_radius){
+ sub_config.border_radius = parseFloat(sub_config.border_radius) + parseFloat(config.border_width) / 2
+ }
+ await this.drawRect(sub_config)
+ }
+
+ let color = config.color || 'white'
+ config.x = (parseFloat(config.x) + config.border_width / 2)
+ config.y = (parseFloat(config.y) + config.border_width / 2)
+ config['color'] = color
+ this.ctx.fillStyle = color;
+ if(config.is_radius || config.border_radius){
+ this.setNativeBorderRadius(config)
+ this.ctx.fill()
+ }else{
+ console.log('config.border_width',config.border_width)
+ this.ctx.fillRect(this.compatibilitySize(config.x*this.scale),this.compatibilitySize(config.y*this.scale),this.compatibilitySize(parseFloat(config.w)*this.scale),this.compatibilitySize(parseFloat(config.h)*this.scale))
+ }
+ resolve()
+ })
+ },
+ /**
+ * Draw image
+ * @param {Object} config
+ * @param {String} config.url 图片链接
+ * @param {Number} config.x x坐标
+ * @param {Number} config.y y坐标
+ * @param {Number} config.w 图片宽度(px)
+ * @param {Number} config.h 图片高度(px)
+ * @param {Number} config.border_width 边大小
+ * @param {Number} config.border_color 边颜色
+ * @param {Number} config.is_radius 是否开启圆图(1.1.6及以下版本废弃,请使用border_radius)
+ * @param {Number} config.border_radius 圆角弧度
+ */
+ drawImage(config){
+ return new Promise(async (resolve,reject)=>{
+ if(config.url){
+ let type = 0 // 1、network image 2、native image 3、base64 image
+ let image_url
+ let reg = /^https?/ig;
+ if(reg.test(config.url)){
+ type = 1
+ }else{
+ if((config.url.indexOf("data:image/png;base64") != -1) || config.url.indexOf("data:image/jpeg;base64") != -1 || config.url.indexOf("data:image/gif;base64") != -1){
+ type = 3
+ }else{
+ type = 2
+ }
+ }
+ if(type == 1){
+ // network image
+ await this.downLoadNetworkFile(config.url).then(res=>{ // two function
+ image_url = res
+ }).catch(err=>{
+ reject(err)
+ return;
+ })
+ }else if(type == 2){
+ // native image
+ const imageInfoResult = await uni.getImageInfo({
+ src: config.url
+ });
+ try{
+ if(imageInfoResult.length <= 1){
+ reject(imageInfoResult[0].errMsg + ':404')
+ return
+ }
+ }catch(e){
+ reject(e+':500')
+ return
+ }
+ let base64 = await this.urlToBase64({url:imageInfoResult[1].path})
+ // #ifdef MP-WEIXIN
+ await this.base64ToNative({url:base64}).then(res=>{
+ image_url = res
+ }).catch(err=>{
+ reject(JSON.stringify(err)+":501")
+ return;
+ })
+ // #endif
+ // #ifndef MP-WEIXIN
+ image_url = base64
+ // #endif
+
+ }else if(type == 3){
+ // #ifdef MP-WEIXIN
+ await this.base64ToNative({url:config.url}).then(res=>{
+ image_url = res
+ }).catch(err=>{
+ reject(JSON.stringify(err)+":500")
+ return;
+ })
+ // #endif
+ // #ifndef MP-WEIXIN
+ image_url = config.url
+ // #endif
+ }else{
+ reject("Other Type Errors:101")
+ return
+ }
+ if(config.border_width){
+ let border_radius = 0
+ if(config.border_radius){
+ let multiple = config.w / config.border_radius
+ border_radius = (parseFloat(config.w) + parseFloat(config.border_width)) / multiple
+ }
+ // drawRect
+ await this.drawRect({
+ x:parseFloat(config.x) - parseFloat(config.border_width)/2,
+ y:parseFloat(config.y) - parseFloat(config.border_width)/2,
+ w:parseFloat(config.w) + parseFloat(config.border_width),
+ h:parseFloat(config.h) + parseFloat(config.border_width),
+ color:config.border_color,
+ border_radius:border_radius,
+ border_width:config.border_width,
+ is_radius:config.is_radius
+ })
+ }
+
+
+
+ if(config.border_radius){
+ config.color = config.color?config.color:'rgba(0,0,0,0)'
+
+ // 圆角有白边,+0.5的误差
+ config.w = config.w + 0.3
+ config.h = config.h + 0.3
+
+ this.setNativeBorderRadius(config)
+ }else if(config.is_radius){
+ //已废弃 is_radius
+ this.ctx.setStrokeStyle("rgba(0,0,0,0)")
+ this.ctx.save()
+ this.ctx.beginPath()
+ this.ctx.arc(this.compatibilitySize(parseFloat(config.x)*this.scale+parseFloat(config.w)*this.scale/2), this.compatibilitySize(parseFloat(config.y)*this.scale+parseFloat(config.h)*this.scale/2), this.compatibilitySize(parseFloat(config.w)*this.scale/2), 0, 2 * Math.PI, false)
+ this.ctx.stroke();
+ this.ctx.clip()
+ }
+
+ await this.ctx.drawImage(image_url,this.compatibilitySize(parseFloat(config.x)*this.scale),this.compatibilitySize(parseFloat(config.y)*this.scale),this.compatibilitySize(parseFloat(config.w)*this.scale),this.compatibilitySize(parseFloat(config.h)*this.scale))
+ this.ctx.restore() //Restore previously saved drawing context
+ resolve()
+ }else{
+ let err_msg = "Links cannot be empty:101"
+ reject(err_msg)
+ }
+ })
+ },
+ /**
+ * base64 to native available path
+ * @param {Object} config
+ */
+ base64ToNative(config){
+ return new Promise((resolve,reject)=>{
+ let fileName = new Date().getTime()
+ var filePath = `${wx.env.USER_DATA_PATH}/${fileName}_rCanvas.png`
+ wx.getFileSystemManager().writeFile({
+ filePath: filePath,
+ data: config.url.replace(/^data:\S+\/\S+;base64,/, ''),
+ encoding: 'base64',
+ success: function() {
+ resolve(filePath)
+ },
+ fail: function(error) {
+ reject(error)
+ }
+ })
+ })
+ },
+ /**
+ * native url to base64
+ * @param {Object} config
+ */
+ urlToBase64(config){
+ return new Promise(async (resolve,reject)=>{
+ if (typeof window != 'undefined') {
+ await this.downLoadNetworkFile(config.url).then(res=>{ // two function
+ resolve(res)
+ }).catch(err=>{
+ reject(err)
+ })
+ }else if (typeof plus != 'undefined') {
+ plus.io.resolveLocalFileSystemURL(config.url,(obj)=>{
+ obj.file((file)=>{
+ let fileReader = new plus.io.FileReader()
+ fileReader.onload = (res)=>{
+ resolve(res.target.result)
+ }
+ fileReader.onerror = (err)=>{
+ reject(err)
+ }
+ fileReader.readAsDataURL(file)
+ }, (err)=>{
+ reject(err)
+ })
+ },(err)=>{
+ reject(err)
+ })
+ }else if(typeof wx != 'undefined'){
+ wx.getFileSystemManager().readFile({
+ filePath: config.url,
+ encoding: 'base64',
+ success: function(res) {
+ resolve('data:image/png;base64,' + res.data)
+ },
+ fail: function(error) {
+ reject(error)
+ }
+ })
+ }
+ })
+ },
+ setNativeBorderRadius(config){
+ let border_radius = config.border_radius?(parseFloat(config.border_radius)*this.scale):(20*this.scale)
+ if ((parseFloat(config.w)*this.scale) < 2 * border_radius) border_radius = (parseFloat(config.w)*this.scale) / 2;
+ if ((parseFloat(config.h)*this.scale) < 2 * border_radius) border_radius = (parseFloat(config.h)*this.scale) / 2;
+ this.ctx.beginPath();
+ this.ctx.moveTo(this.compatibilitySize((parseFloat(config.x)*this.scale) + border_radius), this.compatibilitySize((parseFloat(config.y)*this.scale)));
+ this.ctx.arcTo(this.compatibilitySize((parseFloat(config.x)*this.scale) + (parseFloat(config.w)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale)), this.compatibilitySize((parseFloat(config.x)*this.scale) + (parseFloat(config.w)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale) + (parseFloat(config.h)*this.scale)), this.compatibilitySize(border_radius));
+ this.ctx.arcTo(this.compatibilitySize((parseFloat(config.x)*this.scale) + (parseFloat(config.w)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale) + (parseFloat(config.h)*this.scale)), this.compatibilitySize((parseFloat(config.x)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale) + (parseFloat(config.h)*this.scale)), this.compatibilitySize(border_radius));
+ this.ctx.arcTo((this.compatibilitySize(parseFloat(config.x)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale) + (parseFloat(config.h)*this.scale)), this.compatibilitySize((parseFloat(config.x)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale)), this.compatibilitySize(border_radius));
+ this.ctx.arcTo(this.compatibilitySize((parseFloat(config.x)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale)), this.compatibilitySize((parseFloat(config.x)*this.scale) + (parseFloat(config.w)*this.scale)), this.compatibilitySize((parseFloat(config.y)*this.scale)), this.compatibilitySize(border_radius));
+ this.ctx.closePath();
+ this.ctx.strokeStyle = config.color || config.border_color || 'rgba(0,0,0,0)'; // 设置绘制边框的颜色
+ this.ctx.stroke();
+ this.ctx.save()
+ this.ctx.clip();
+
+ },
+ /**
+ * Download network file
+ * @param {Object} url : download url
+ */
+ downLoadNetworkFile(url){
+ return new Promise((resolve,reject)=>{
+ uni.downloadFile({
+ url,
+ success:(res)=>{
+ if(res.statusCode == 200){
+ resolve(res.tempFilePath)
+ }else{
+ reject("Download Image Fail:102")
+ }
+ },
+ fail:(err)=>{
+ reject("Download Image Fail:101")
+ }
+ })
+ })
+ },
+ /**
+ * Save image to natice
+ * @param {Object} filePath : native imageUrl
+ */
+ saveImage(filePath){
+ return new Promise((resolve,reject)=>{
+ if(!filePath){
+ reject("FilePath cannot be null:101")
+ return;
+ }
+
+ // #ifdef H5
+ var createA = document.createElement("a");
+ createA.download = filePath;
+ createA.href = filePath;
+ document.body.appendChild(createA);
+ createA.click();
+ createA.remove();
+ resolve()
+ // #endif
+
+ // #ifndef H5
+ uni.saveImageToPhotosAlbum({
+ filePath: filePath,
+ success:(res)=>{
+ resolve(res)
+ },
+ fail:(err)=>{
+ reject(err)
+ }
+ })
+ // #endif
+ })
+ }
+ }
+}
diff --git a/components/r-canvas/r-canvas.vue b/components/r-canvas/r-canvas.vue
new file mode 100644
index 0000000..5722790
--- /dev/null
+++ b/components/r-canvas/r-canvas.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
index bbd71fa..b4155c7 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,16 @@
{
- "dependencies": {
- "uview-ui": "^1.8.4"
- }
+ "dependencies": {
+ "uview-ui": "^1.8.4"
+ },
+ "id": "r-canvas",
+ "name": "海报生成,随心所欲绘制样式,原生canvas方法的二次封装,自定义函数,持续更新",
+ "version": "1.3.1",
+ "description": "图片不失帧,保留原有画质,canvas方法扩展,暴露原生实例,可自行扩展,最好用的canvas插件",
+ "keywords": [
+ "canvas",
+ "画布生成图片",
+ "绘制图片",
+ "商品海报",
+ "朋友圈海报"
+ ]
}
diff --git a/pages.json b/pages.json
index 9257993..689c477 100644
--- a/pages.json
+++ b/pages.json
@@ -4,19 +4,19 @@
},
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
- "path": "pages/integral/integral",
- "style": {
- "navigationBarTitleText": "积分",
- "enablePullDownRefresh": false,
- "navigationBarBackgroundColor": "#ffffff"
- }
- },{
"path": "pages/startup/startup",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},{
+ "path": "pages/integral/integral",
+ "style": {
+ "navigationBarTitleText": "积分",
+ "enablePullDownRefresh": false,
+ "navigationBarBackgroundColor": "#ffffff"
+ }
+ }, {
"path": "pages/information/information",
"style": {
"navigationBarTitleText": "完善个人信息",
diff --git a/pages/CommodityOrder/CommodityOrder.vue b/pages/CommodityOrder/CommodityOrder.vue
index a270278..bcf3f10 100644
--- a/pages/CommodityOrder/CommodityOrder.vue
+++ b/pages/CommodityOrder/CommodityOrder.vue
@@ -25,15 +25,25 @@
{{item.goodsName}}
- ¥{{item.goodsPrice}}
+ ¥{{item.goodsPrice}}
型号:{{item.goodsAttributeName}}
×{{item.goodsCount}}
- 实付款:
- ¥{{item.totalPrice}}
+
+ 实付款:
+
+
+ 实付:
+
+ ¥{{item.totalPrice}}
+ {{item.integralExchangeSill}}
+
+ 积分
+
@@ -74,7 +84,7 @@
共1件
- 为了保证你的售后权益,请收到商品确认无误后再确认收货
+ 为了保证您的售后权益,请收到商品确认无误后再确认收货
确定
@@ -252,20 +262,16 @@
this.pageNum = 1;
this.baseurl = baseurl;
let that = this
- try {
- const value = uni.getStorageSync('openid');
- if (value) {} else {
- uni.navigateTo({
- url: '/pages/login/login'
- })
- }
- } catch (e) {}
- try {
- const value3 = uni.getStorageSync('Refresh');
- if (value3) {
- that.goodsOrderinfo();
- }
- } catch (e) {}
+ const value = uni.getStorageSync('openid');
+ if (value) {} else {
+ uni.navigateTo({
+ url: '/pages/login/login'
+ })
+ }
+ const value3 = uni.getStorageSync('Refresh');
+ if (value3) {
+ that.goodsOrderinfo();
+ }
},
onLoad(options) { //开局调用
let that = this
diff --git a/pages/Healthknowledge/Healthknowledge.vue b/pages/Healthknowledge/Healthknowledge.vue
index 0631d83..3d357e9 100644
--- a/pages/Healthknowledge/Healthknowledge.vue
+++ b/pages/Healthknowledge/Healthknowledge.vue
@@ -148,7 +148,7 @@
.item {
width: 100%;
- height: 200rpx;
+ height: 250rpx;
position: relative;
border-bottom: 2rpx solid #CDC9C9;
@@ -157,8 +157,8 @@
right: 0;
top: 50%;
transform: translateY(-50%);
- width: 253rpx;
- height: 164rpx;
+ width: 200rpx;
+ height: 200rpx;
border-radius: 10rpx;
}
@@ -176,6 +176,13 @@
left: 0;
width: 60%;
font-size: 30rpx;
+ text-overflow: -o-ellipsis-lastline;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 5; //行数需设置
+ line-clamp: 5;
+ -webkit-box-orient: vertical;
}
}
}
diff --git a/pages/Personal/Personal.vue b/pages/Personal/Personal.vue
index f6191c6..1e6259a 100644
--- a/pages/Personal/Personal.vue
+++ b/pages/Personal/Personal.vue
@@ -34,15 +34,21 @@
积分
- {{appPersonallist.integral}}
+
+ {{appPersonallist.integral}}
+
+ 0
优惠券
-
- {{appPersonallist.patientCouponCount}}张
+
+ {{appPersonallist.patientCouponCount}}
+
+ 0张
diff --git a/pages/homepage/homepage.vue b/pages/homepage/homepage.vue
index 12ed3de..55f5dd8 100644
--- a/pages/homepage/homepage.vue
+++ b/pages/homepage/homepage.vue
@@ -372,9 +372,13 @@
left: 0;
width: 65%;
font-size: 30rpx;
- // overflow: hidden;
- // text-overflow: ellipsis;
- // white-space: nowrap;
+ text-overflow: -o-ellipsis-lastline;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 5; //行数需设置
+ line-clamp: 5;
+ -webkit-box-orient: vertical;
}
}
}
diff --git a/pages/integral/integral.vue b/pages/integral/integral.vue
index 4c2f30b..e6fc9d5 100644
--- a/pages/integral/integral.vue
+++ b/pages/integral/integral.vue
@@ -31,19 +31,19 @@
{{item.goodsName}}
- {{item.attributeDetailsName}}
+ {{item.integralExchangeCount}}{{item.goodsUnit}}
需使用
{{item.integralExchangeSill}}
积分兑换
-
+
立即兑换
-
+
获取方式
@@ -77,18 +77,82 @@
+ {{list.inviteFriends}}积分
-
+
去完成
-
-
-
+
+
+
+
+
+
+
+
+
+ {{goodsitem.goodsName}}
+
+
+ 暂无
+
+
+
+ {{goodsitem.integralExchangeSill}}积分
+
+
+
+ 库存数量:{{goodsitem.goodsStock}}
+
+
+
+
+
+
+ {{updata.receiver}},{{updata.phone}}
+
+
+ {{updata.receiveAddress}}
+
+
+ 前往完善个人信息
+
+
+
+
+
+
+
+
+
+
+
+
+ {{goodsitem.integralExchangeCount}}{{goodsitem.goodsUnit}}
+
+
+
+
+
+ 立即兑换
+
+
+
+
+
+
+ 保存到相册
+
+
+ 分享给好友
+
+
@@ -96,46 +160,309 @@
import {
signIn,
selectPatientSignIn,
- selectExchangeGoods
+ selectExchangeGoods,
+ integralGoodsOrder
} from '@/api/integral/index.js'
import {
inviteFriends
} from '@/api/Personal/Personal.js';
+ import {
+ goodPatientInfo
+ } from '@/api/modifyAddress/modifyAddress.js';
import baseurl from '../../api/baseurl';
+ import rCanvas from "@/components/r-canvas/r-canvas.vue"
export default {
-
+ components: {
+ rCanvas
+ },
data() {
return {
- integral: 0,
- gainshow: false,
- yaoqingshow: false,
+ baseurl: '',
patientId: null,
+ integral: 0,
+ gainshow: false, //积分邀请
+ buyshow: false, //兑换购买
+ yaoqingshow: false,
+ yaoqingimg: null,
list: null,
- inviteimg: null,
+ inviteimg: null, //邀请二维码
pageNum: 1,
pageSize: 10,
goodstotal: 0,
goodslist: null,
+ goodsitem: null,
+ userid: null,
+ updata: {
+ "orderChannel": 'WECHAT_APPLET',
+ "originalTotalPrice": null,
+ "integralExchangeSill": null,
+ "integralExchangeCount": null,
+ "orderType": "INTEGRAL_EXCHANGE",
+ "buySource": "SHOPPING_MALL",
+ "integralDeductionCount": null,
+ "attributeDetailsId": null,
+ "discountPrice": null,
+ "giveIntegral": null,
+ "goodsAttributeContent": null,
+ "goodsAttributeDetailsId": null,
+ "goodsAttributeId": null,
+ "goodsAttributeName": null,
+ "goodsCount": null,
+ "goodsName": null,
+ "goodsPrice": null,
+ "goodsStock": null,
+ "nurseStationId": null,
+ "patientId": null,
+ "phone": "18963146613",
+ "receiveAddress": null,
+ "receiver": null,
+ }
};
- },
- onReady() {
-
},
onLoad(options) {
+ this.baseurl = baseurl
this.integral = options.integral
var that = this
this.selectExchangeGoodsinfo();
const value = uni.getStorageSync('patientId');
if (value) {
that.patientId = value
+ that.updata.patientId = value
that.selectPatientSignInifo();
- inviteFriends(value).then(res => {
- that.inviteimg = res.msg
- })
+ that.goodsList();
}
},
+ onShow() {
+ var that = this
+ this.baseurl = baseurl
+ const value = uni.getStorageSync('patientId');
+ if (value) {
+ that.updata.patientId = value
+ goodPatientInfo(value).then(res => {
+ if (res.code == 200) {
+ var user = res.data.filter(e => e.id == that.userid)
+ if (user.length >= 1) {
+ that.updata.receiver = user[0].receiveName
+ that.updata.receiveAddress = user[0].areaName + user[0].receiveAddress
+ that.updata.phone = user[0].receivePhone
+ that.userid = user[0].id
+ } else {
+ that.updata.receiver = res.data[0].receiveName
+ that.updata.receiveAddress = res.data[0].areaName + res.data[0].receiveAddress
+ that.updata.phone = res.data[0].receivePhone
+ that.userid = res.data[0].id
+ }
+ }
+ })
+ } else {}
+ let useritem = null
+ uni.$on('updata', function(data) {
+ if (data.useritem) {
+ useritem = JSON.parse(data.useritem)
+ that.updata.receiver = useritem.receiveName
+ that.updata.phone = useritem.receivePhone
+ that.updata.receiveAddress = useritem.areaName + useritem.receiveAddress
+ that.userid = useritem.id
+ }
+ })
+ },
methods: {
- yaoqingshowfalse() {},
+ yaoqingshowtrue() {
+ this.yaoqingshow = true
+ this.$nextTick(async () => {
+ await inviteFriends(this.patientId).then(res => {
+ this.inviteimg = res.msg
+ })
+ uni.showLoading({
+ title: '加载中'
+ });
+ // 初始化
+ await this.$refs.rCanvas.init({
+ canvas_id: "rCanvas"
+ })
+ // 画图
+ await this.$refs.rCanvas.drawImage({
+ url: "/static/yaoqinghaoyou.png",
+ x: 0,
+ y: 0,
+ w: 330,
+ h: 600
+ }).catch(err_msg => {
+ uni.showToast({
+ title: err_msg,
+ icon: "none"
+ })
+ })
+ await this.$refs.rCanvas.drawImage({
+ url: baseurl + this.inviteimg,
+ x: 100,
+ y: 370,
+ w: 130,
+ h: 130
+ }).catch(err_msg => {
+ uni.showToast({
+ title: err_msg,
+ icon: "none"
+ })
+ })
+ // 画文字
+ await this.$refs.rCanvas.drawText({
+ text: "智慧康养泉城,医护关怀到家",
+ x: 165,
+ y: 330,
+ font_color: "#444444",
+ font_size: 12,
+ font_weight: 600,
+ text_align: 'center'
+ }).catch(err_msg => {
+ uni.showToast({
+ title: err_msg,
+ icon: "none"
+ })
+ })
+ await this.$refs.rCanvas.drawText({
+ text: "超多福利,快来体验吧!",
+ x: 165,
+ y: 350,
+ font_color: "#444444",
+ font_size: 12,
+ font_weight: 600,
+ text_align: 'center'
+ }).catch(err_msg => {
+ uni.showToast({
+ title: err_msg,
+ icon: "none"
+ })
+ })
+ await this.$refs.rCanvas.drawText({
+ text: "泉医到家小程序",
+ x: 165,
+ y: 530,
+ font_color: "#444444",
+ font_size: 10,
+ text_align: 'center'
+ }).catch(err_msg => {
+ uni.showToast({
+ title: err_msg,
+ icon: "none"
+ })
+ })
+ await this.$refs.rCanvas.drawText({
+ text: "(长按识别二维码开启健康之旅)",
+ x: 165,
+ y: 543,
+ font_color: "#444444",
+ font_size: 7,
+ text_align: 'center'
+ }).catch(err_msg => {
+ uni.showToast({
+ title: err_msg,
+ icon: "none"
+ })
+ })
+ // 生成海报
+ await this.$refs.rCanvas.draw((res) => {
+ this.yaoqingimg = res.tempFilePath
+ uni.hideLoading();
+ //res.tempFilePath:生成成功,返回base64图片
+ // 保存图片
+ // this.$refs.rCanvas.saveImage(res.tempFilePath)
+ })
+ })
+ },
+ //保存
+ draw() {
+ // 保存图片
+ this.$refs.rCanvas.saveImage(this.yaoqingimg).then(res => {
+ uni.showToast({
+ title: '保存成功',
+ duration: 2000
+ });
+ }).catch(err => {
+ uni.showToast({
+ icon: 'error',
+ title: '保存失败',
+ duration: 2000
+ });
+ })
+ },
+ //分享
+ fenx() {
+ wx.showShareImageMenu({
+ path: this.yaoqingimg,
+ })
+ },
+ yaoqingshowfalse() {
+ this.yapqingshow = false;
+ this.$nextTick(async () => {
+ await this.$refs.rCanvas.clearCanvas((res) => {
+ console.log(res)
+ })
+ await this.$refs.rCanvas.setCanvasWidth(0)
+ await this.$refs.rCanvas.setCanvasHeight(0)
+ })
+ },
+ //兑换
+ upbuy() {
+ integralGoodsOrder(this.updata).then(res => {
+ if (res.code == 200) {
+ this.$refs.uToast.show({
+ title: '兑换商品成功',
+ type: 'success'
+ })
+ this.buyshow = false
+ } else {
+ this.$refs.uToast.show({
+ title: '兑换商品失败',
+ type: 'error'
+ })
+ }
+ })
+ },
+ //跳转到全部收货地址
+ upaddress() {
+ if (this.updata.receiver) {
+ uni.navigateTo({
+ url: `/pages/modifyAddress/modifyAddress?updata=${JSON.stringify(this.updata)}`
+ })
+ } else {
+ const value = uni.getStorageSync('openid');
+ const value2 = uni.getStorageSync('patientId');
+ if (value && value2) {
+ uni.navigateTo({
+ url: '/pages/information/information'
+ })
+ } else {
+ this.$refs.uToast.show({
+ title: '未登录,请先登录',
+ type: 'error'
+ })
+ if (this.timer) {
+ clearTimeout(this.timer)
+ }
+ this.timer = setTimeout(e => {
+ uni.navigateTo({
+ url: '/pages/login/login'
+ })
+ }, 1500)
+ }
+ }
+ },
+ ///兑换
+ buyshowtrue(item) {
+ this.buyshow = true
+ this.goodsitem = item
+ this.updata.goodsAttributeName = this.goodsitem.attributeDetailsName
+ this.updata.goodsAttributeId = this.goodsitem.goodsAttributeId
+ this.updata.goodsAttributeDetailsId = this.goodsitem.attributeDetailsId
+ this.updata.integralExchangeSill = this.goodsitem.integralExchangeSill
+ this.updata.integralExchangeCount = this.goodsitem.integralExchangeCount
+ this.updata.originalTotalPrice = 0
+ this.updata.goodsStock = this.goodsitem.goodsStock
+ this.updata.goodsName = this.goodsitem.goodsName
+ this.updata.goodsPrice = this.goodsitem.goodsPrice
+ this.updata.goodsCount = 1
+ },
//可兑换商品
selectExchangeGoodsinfo() {
selectExchangeGoods(this.pageNum, this.pageSize).then(res => {
@@ -165,6 +492,23 @@
}
})
},
+ // 收件人
+ goodsList() {
+ goodPatientInfo(this.patientId).then(res => {
+ var list = res.data.filter(e => e.defaultAddressFlag == 1)
+ if (list.length >= 1) {
+ this.updata.receiver = list[0].receiveName
+ this.updata.receiveAddress = list[0].areaName + list[0].receiveAddress
+ this.updata.phone = list[0].receivePhone
+ this.userid = list[0].id
+ } else {
+ this.updata.receiver = res.data[0].receiveName
+ this.updata.receiveAddress = res.data[0].areaName + res.data[0].receiveAddress
+ this.updata.phone = res.data[0].receivePhone
+ this.userid = res.data[0].id
+ }
+ })
+ },
},
onReachBottom() { //下滑加载
if (this.goodslist.length >= this.goodstotal) {} else {
@@ -189,21 +533,246 @@