Browse Source

提交

dev
douzhuo 1 year ago
parent
commit
d55ec78eac
12 changed files with 2642 additions and 697 deletions
  1. +75
    -0
      components/html2canvas/html2canvas.vue
  2. +735
    -0
      components/r-canvas/r-canvas.js
  3. +26
    -0
      components/r-canvas/r-canvas.vue
  4. +1
    -0
      main.js
  5. +47
    -1
      package-lock.json
  6. +575
    -446
      pages/mine/messageDetail.vue
  7. +39
    -15
      pages/mine/messageList.vue
  8. +471
    -73
      pages/mine/reportExcel/dayReport.vue
  9. +513
    -150
      pages/mine/reportExcel/weekReport.vue
  10. +152
    -0
      static/libs/image-tools.js
  11. +7
    -0
      store/index.js
  12. +1
    -12
      utils/domain.js

+ 75
- 0
components/html2canvas/html2canvas.vue View File

@@ -0,0 +1,75 @@
<template>
<view>
<view class="html2canvas" :prop="domId" :change:prop="html2canvas.create">
<slot></slot>
</view>
</view>
</template>

<script>
import { base64ToPath } from '@/static/libs/image-tools.js';
export default {
name: 'html2canvas',
props: {
domId: {
type: String,
required: true
}
},
methods: {
async renderFinish(base64) {
try{
const imgPath = await base64ToPath(base64, '.jpeg');
this.$emit('renderFinish', imgPath);
}catch(e){
//TODO handle the exception
console.log('html2canvas error', e)
}
},
showLoading() {
uni.showToast({
title: "正在生成海报",
icon: "none",
mask: true,
duration: 100000
})
},
hideLoading() {
uni.hideToast();
}
}
}
</script>

<script module="html2canvas" lang="renderjs">
import html2canvas from 'html2canvas';
export default {
methods: {
async create(domId) {
try {
this.$ownerInstance.callMethod('showLoading', true);
const timeout = setTimeout(async ()=> {
const shareContent = document.querySelector(domId);
const canvas = await html2canvas(shareContent,{
width: shareContent.offsetWidth,//设置canvas尺寸与所截图尺寸相同,防止白边
height: shareContent.offsetHeight,//防止白边
logging: true,
useCORS: true
});
const base64 = canvas.toDataURL('image/jpeg', 1);
this.$ownerInstance.callMethod('renderFinish', base64);
this.$ownerInstance.callMethod('hideLoading', true);
clearTimeout(timeout);
}, 500);
} catch(error){
console.log(error)
}
}
}
}
</script>


<style lang="scss">

</style>

+ 735
- 0
components/r-canvas/r-canvas.js View File

@@ -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
})
}
}
}

+ 26
- 0
components/r-canvas/r-canvas.vue View File

@@ -0,0 +1,26 @@
<template>
<view>
<view class="r-canvas-component" :style="{width:canvas_width/scale+'px',height:canvas_height/scale+'px'}" :class="{'hidden':hidden}">
<canvas class="r-canvas" v-if="canvas_id" :canvas-id="canvas_id" :id="canvas_id" :style="{width:canvas_width+'px',height:canvas_height+'px','transform': `scale(${r_canvas_scale})`}"></canvas>
</view>
</view>
</template>

<script>
import rCanvasJS from "./r-canvas.js"
export default {
mixins:[rCanvasJS]
}
</script>
<style>
.r-canvas{
transform-origin: 0 0;
}
.r-canvas-component{
overflow: hidden;
}
.r-canvas-component.hidden{
position: fixed;
top:-5000upx;
}
</style>

+ 1
- 0
main.js View File

@@ -12,6 +12,7 @@ let zaudio = new ZAudio({

Vue.prototype.$zaudio = zaudio
Vue.prototype.$dayjs = dayjs;
Vue.prototype.$store = store;

import common from 'utils/common.js'
Vue.prototype.$noMultipleClicks = common.noMultipleClicks;


+ 47
- 1
package-lock.json View File

@@ -1,3 +1,49 @@
{
"lockfileVersion": 1
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
},
"css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"requires": {
"utrie": "^1.0.2"
}
},
"html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"requires": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
}
},
"text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"requires": {
"utrie": "^1.0.2"
}
},
"utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"requires": {
"base64-arraybuffer": "^1.0.2"
}
},
"wxml2canvas": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/wxml2canvas/-/wxml2canvas-1.0.1.tgz",
"integrity": "sha512-AdWvxgTjJtW/m6Cki1cwGO0HOERKU8O9V3RcCz8UyqJbrPF7e8Nv27/epYiIs64HlbPTKWTLl7ECjQi6UVducA=="
}
}
}

+ 575
- 446
pages/mine/messageDetail.vue
File diff suppressed because it is too large
View File


+ 39
- 15
pages/mine/messageList.vue View File

@@ -4,9 +4,9 @@
<view class="m-nav">
<view class="m-n-lside">
<image src="@/static/images/notice.png" mode=""></image>
全部102条消息
全部{{ count }}条消息
</view>
<view class="m-n-rside">
<view class="m-n-rside" @click="allRead">
全部已读
</view>
</view>
@@ -48,7 +48,7 @@
:scroll-y="true" class="scroll-Y" @scrolltolower="lower">
<template v-if="updateAnnList.length!=0">
<block v-for="(item,index) in updateAnnList" :key="index">
<view class="upgradeItem" @click="goDetail(item.content,item.id,item.title)">
<view class="upgradeItem" @click="goDetail(item)">
<view class="right">
<view class="title">
{{item.title}}
@@ -85,10 +85,13 @@
updateAnnList: [],
sysItemList: [],
list: [{
name: '接待报告'
name: '接待报告',
id: 1, // 1日报 2周报 3其他(非3为接待报告,3是系统消息)
}, {
name: '升级公告',
id: 3, // 1日报 2周报 3其他(非3为接待报告,3是系统消息)
}],
count: 0, // 全部条数
current: 0,
pageNum: 1,
pageSize: 10,
@@ -108,7 +111,7 @@
},
onPullDownRefresh() {
this.updateInit()
this.initPage()
setTimeout(function() {
uni.stopPullDownRefresh();
}, 1000);
@@ -139,11 +142,32 @@
this.updateInit()
},
initPage() {
this.updateAnnList = []
this.pageNum = 1
this.updateInit()
},
// 全部标记已读
allRead() {
this.$u.get('/zkMessage/updateState', { accountId: uni.getStorageSync('weapp_session_userInfo_data').accountId, projectId: uni.getStorageSync('buildingID').id, }).then(res => {
uni.showToast({
title: '全部已读成功!',
duration: 2000
});
this.initPage()
}).catch(e => {
console.log(e)
})
},
updateInit() {
uni.request({
url: config.service.updateList,
method: "GET",
data: {
messageType: this.list[this.current].id,
projectId: uni.getStorageSync('buildingID').id,
id: uni.getStorageSync('weapp_session_userInfo_data').accountId,
num: this.pageNum,
size: this.pageSize
@@ -161,6 +185,7 @@
duration: 2000
});
} else {
this.count = res.data.count
if (this.pageNum != 1) {
this.updateAnnList = [...this.updateAnnList, ...res.data.data.list.results];
} else {
@@ -171,30 +196,29 @@
}
})
},
goDetail(text, id, title) {
let link = encodeURIComponent(JSON.stringify(text))
goDetail(data) {
this.$store.commit('setMessageObj', data)
uni.navigateTo({
url: "./messageDetail?content=" + link + "&id=" + id + "&tit=" + title
url: "./messageDetail"
})
},
// 跳转日报
goReception(item, index) {
if (index == 2) {
goReception(data, index) {
this.$store.commit('setMessageObj', data)
if (data.title == '周报') {
uni.navigateTo({
url: `/pages/mine/reportExcel/weekReport`
url: `/pages/mine/reportExcel/weekReport?id=${data.id}`
})
} else {
uni.navigateTo({
url: `/pages/mine/reportExcel/dayReport`
url: `/pages/mine/reportExcel/dayReport?id=${data.id}`
})
}
},
change(index) {
this.current = index;
if (this.current == 1) {
this.updateInit()
}
this.initPage()
}
}
}


+ 471
- 73
pages/mine/reportExcel/dayReport.vue View File

@@ -2,73 +2,427 @@
<view class="pages">
<!-- 导航栏 -->
<view class="nav-header">
<u-navbar title="数智工牌日报" titles="05.02"></u-navbar>
<u-navbar title="数智工牌日报" :titles="$options.filters.fomatDate(weekObj.createTime)"></u-navbar>
</view>
<!-- 日报内容部分 -->
<view class="container">
<view class="container" ref="lists">
<!-- 头部日报卡 -->
<view class="c-head-card">
<view class="c-title-text">
桃源避暑山庄新型项目数智工牌日报
<text class="date">01月27日</text>
{{ projectName }}数智工牌日报
<text class="date">{{ weekObj.createTime | fomatDate }}</text>
</view>
<view class="creative-time">
生成时间:2022-01-27 22:00
生成时间:{{ weekObj.createTime || '--' }}
</view>
</view>
<!-- 循环渲染的数据 -->
<view class="dateList">
<!-- -->
<view class="arrs">
<block v-for="(data, index) in 11" :key="index">
<view class="arrs-items">
<view class="left">
{{ index+1 }}
</view>
<view class="right">
<view class="r-title">
<text>接待量:</text>
<text class="num">879次</text>

<view class="arrs-items index1">
<view class="left">
1
</view>
<view class="right">
<view class="r-title">
<text>接待量:</text>
</view>

<view class="r-box">
<view class="r-box-item">
<text>接待量</text><text>{{ weekObj.receptionCount || 0 }}</text>
</view>
<view class="r-box">
<view class="r-box-item">
<text>接待量</text><text>100</text>
</view>
<view class="r-box-item">
<text>有效接待</text><text>100</text>
</view>
<view class="r-box-item-lang">
<view>有效接待率<text>80%</text></view>
<view class="contrast">对比昨天<text class="down">-5%</text></view>
</view>
<view class="r-box-item">
<text>有效接待</text><text>{{ weekObj.activeCustomer || 0 }}</text>
</view>
<view class="r-box-item-lang">
<view>有效接待率<text>{{ weekObj.validReceptionRate || 0 }}%</text></view>
<view class="contrast">对比昨天<text
:class="{down: weekObj.validReceptionRatePK < 0, up: weekObj.validReceptionRatePK > 0}">{{ weekObj.validReceptionRatePK || 0 }}</text>
</view>
</view>
</view>

</view>
</view>

<view class="arrs-items index2">
<view class="left">
2
</view>
<view class="right">
<view class="r-title">
<text>销讲执行率:</text>
</view>
<view class="r-box">
<view class="r-box-item-lang">
<view>销讲执行率<text>{{ weekObj.fraction || 0 }}%</text></view>
<view class="contrast">对比昨天<text
:class="{down: weekObj.fractionPK < 0, up: weekObj.fractionPK > 0}">{{ weekObj.fractionPK || 0 }}</text>
</view>
</view>
</view>
</view>
</view>

<view class="arrs-items index3">
<view class="left">
3
</view>
<view class="right">
<view class="r-title">
<text>平均接待时长:</text>
</view>
<view class="r-box">
<view class="r-box-item-lang">
<view>平均接待时长<text>{{ weekObj.avgDuration || 0 }}m</text></view>
<view class="contrast">对比昨天<text
:class="{down: weekObj.avgDurationPK < 0, up: weekObj.avgDurationPK > 0}">{{ weekObj.avgDurationPK }}</text>
</view>
</view>
<view class="ranking">
<block v-for="(rank, rankIndex) in 3" :key="rankIndex">
<view class="ranking-item">
<view class="serial">
{{ rankIndex+1 }}
</view>
<view class="lside">
产品设计
</view>
<view class="rside">
(100%)
</view>
</view>
</view>
</view>

<view class="arrs-items index4">
<view class="left">
4
</view>
<view class="right">
<view class="r-title">
<text>销讲维度执行前三:</text>
</view>
<view class="ranking">
<block v-for="(rank, rankIndex) in carryOutTop" :key="rankIndex">
<view class="ranking-item">
<view class="serial">
{{ rankIndex+1 }}
</view>
</block>
</view>
<view class="lside">
{{ rank.title || '--' }}
</view>
<view class="rside">
({{ rank.value || 0 }}%)
</view>
</view>
</block>
<template v-if="carryOutTop.length == 0">
<view class="empty">
暂无数据
</view>
</template>
</view>
</view>
</block>
</view>

<view class="arrs-items index5">
<view class="left">
5
</view>
<view class="right">
<view class="r-title">
<text>销讲维度执行弱项前三:</text>
</view>
<view class="ranking">
<block v-for="(rank, rankIndex) in carryOutLast" :key="rankIndex">
<view class="ranking-item">
<view class="serial">
{{ rankIndex+1 }}
</view>
<view class="lside">
{{ rank.title || '--' }}
</view>
<view class="rside">
({{ rank.value || 0 }}%)
</view>
</view>
</block>
<template v-if="carryOutLast.length == 0">
<view class="empty">
暂无数据
</view>
</template>
</view>
</view>
</view>

<view class="arrs-items index6">
<view class="left">
6
</view>
<view class="right">
<view class="r-title">
<text>置业顾问平均执行率排名:</text>
</view>
<view class="ranking">
<block v-for="(rank, rankIndex) in consultant" :key="rankIndex">
<view class="ranking-item">
<view class="serial">
{{ rankIndex+1 }}
</view>
<view class="lside">
{{ rank.title || '--' }}
</view>
<view class="rside">
({{ rank.value || 0 }}%)
</view>
</view>
</block>
<template v-if="consultant.length == 0">
<view class="empty">
暂无数据
</view>
</template>
</view>
</view>
</view>

<view class="arrs-items index7">
<view class="left">
7
</view>
<view class="right">
<view class="r-title">
<text>置业顾问平均接访录音排名:</text>
</view>
<view class="ranking">
<block v-for="(rank, rankIndex) in recording" :key="rankIndex">
<view class="ranking-item">
<view class="serial">
{{ rankIndex+1 }}
</view>
<view class="lside">
{{ rank.title || '--' }}
</view>
<view class="rside">
({{ rank.value || 0 }}%)
</view>
</view>
</block>

<template v-if="recording.length == 0">
<view class="empty">
暂无数据
</view>
</template>
</view>
</view>
</view>

<view class="arrs-items index8">
<view class="left">
8
</view>
<view class="right">
<view class="r-title">
<text>执行率最低的顾问:</text>
</view>
<view class="ranking">
<block v-for="(rank, rankIndex) in lowest" :key="rankIndex">
<view class="ranking-item">
<view class="lside">
{{ rank.title || '--' }}
</view>
<view class="rside">
{{ rank.value || 0 }}%
</view>
</view>
</block>
</view>
</view>
</view>

<view class="arrs-items index9">
<view class="left">
9
</view>
<view class="right">
<view class="r-title">
<text>客户画像触达:</text>
<text class="num">{{ weekObj.reachSum || 0 }}次</text>
</view>
</view>
</view>

<view class="arrs-items index10">
<view class="left">
10
</view>
<view class="right">
<view class="r-title">
<text>未标记接待数:</text>
<text class="num up"
style="font-weight: 500;font-size: 34rpx;">{{ weekObj.unlabelledReceptionNum || 0 }}次</text>
</view>
</view>
</view>

<view class="arrs-items index11">
<view class="left">
11
</view>
<view class="right">
<view class="r-title">
<text>设备情况:</text>
</view>
<view class="r-box">
<view class="r-box-item-lang">
<view>在线<text>{{ weekObj.equipmentInfo.onlineNum || 0 }}</text></view>
<view style="margin-left: 24rpx;">
离线<text>{{ weekObj.equipmentInfo.offlineNum || 0 }}</text></view>
</view>
</view>
</view>
</view>

</view>
</view>
</view>

<!-- 底部按钮 -->
<view class="nav-footer">
<view class="footer-item" @click="copy">
复制
</view>

<view class="footer-item full" style="margin-left: 22rpx;">
<button open-type="share" class="fulls">
分享给好友
</button>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
needList: ['XJTop', 'ZXLTop', 'avgJds'], // 需要转换数组的内容
carryOutTop: [], // 销讲维度执行前三:
carryOutLast: [], // 销讲维度执行倒三:
consultant: [], // 置业顾问排名
recording: [], // 录音排名
lowest: [], // 执行率最低的顾问
building: uni.getStorageSync('buildingID'),
id: '', // 消息id
projectName: '', // 项目名称
weekObj: {}, // 日报详情
}
},


onLoad(option) {
if (option.id) this.id = option.id
this.getMessage()
},

onShareAppMessage() {
return {
title: `${this.projectName}数智工牌日报`,
path: `/pages/mine/reportExcel/dayReport?id=${this.id}`
}
},

methods: {
// 获取日报详情
getMessage() {
this.$u.get('/api/zkMessage/findById', {
id: this.id
}).then(res => {
console.log(res)
let data = JSON.parse(res.zkMessage.content)
this.weekObj = {
...res.zkMessage,
...data
}
console.log(this.weekObj, 'this.weekObj')
this.projectName = res.projectName
this.init()
}).catch(e => {
console.log(e)
})
},

copy() {
let str = ``

uni.setClipboardData({
data: str
})
},

// 分割数组排名前三,倒三
getTopThree() {
if (this.weekObj.XJTopList && this.weekObj.XJTopList.length > 0) {
this.carryOutTop = this.weekObj.XJTopList.reverse().slice(0, 3)
this.carryOutLast = this.weekObj.XJTopList.slice(0, 3)
}
if (this.weekObj.ZXLTopList && this.weekObj.ZXLTopList.length > 0) {
this.consultant = this.weekObj.ZXLTopList.reverse().slice(0, 3)
this.lowest.push(this.weekObj.ZXLTopList[0])
}
if (this.weekObj.avgJdsList && this.weekObj.avgJdsList.length > 0) {
console.log(this.weekObj.avgJdsList.slice(0, 3))
this.recording = this.weekObj.avgJdsList.reverse().slice(0, 3)
}
},

init() {
// 把对象转成数组并在后续的步骤方便处理
this.needList.forEach(item => {
if (this.weekObj[item] && Object.keys(this.weekObj[item]).length > 0) {
this.weekObj[item + 'List'] = [] // 销讲执行
for (let i in this.weekObj[item]) {
this.weekObj[item + 'List'].push({
title: i,
value: this.weekObj[item][i]
})
}
}
})
this.sortInitArr()
},

// 排序对象转换后的数组
sortInitArr() {
this.needList.forEach(item => {
if (this.weekObj[item + 'List']) {
this.bubbleSort(this.weekObj[item + 'List'])
}
})
this.getTopThree()
},


// 冒泡排序
bubbleSort(arr) {
for (let i = 0; i < arr.length - 1; i += 1) {
//通过 arr.length 次把第一位放到最后,完成排序
//-i是因为最后的位置是会动态改变的,当完成一次后,最后一位会变成倒数第二位
for (let j = 0; j < arr.length - 1 - i; j += 1) {
if (arr[j].value > arr[j + 1].value) {
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
},
},
filters: {
fomatDate(date) {
if (!date) return '--'
let arr = date.split(' ')
let str = arr[0]
let result = str.split('-')
return `${result[1]}-${result[2]}`
}
}
}
</script>

<style lang="scss" scoped>
@@ -77,17 +431,17 @@
min-height: 100vh;
display: flex;
flex-direction: column;
.nav-header {
flex-shrink: 0;
}
.container {
padding: 30rpx 30rpx 0;
flex-grow: 1;
display: flex;
flex-direction: column;
.c-head-card {
padding: 30rpx;
width: 100%;
@@ -97,13 +451,13 @@
box-shadow: 10rpx 10rpx #2671E2;
display: flex;
flex-direction: column;
.c-title-text {
position: relative;
flex-grow: 1;
font-size: 48rpx;
color: #303030;
.date {
position: absolute;
right: 0;
@@ -112,26 +466,26 @@
color: #303030;
}
}
.creative-time {
margin: 20rpx 0 0 0;
flex-shrink: 0;
}
}
.dateList {
width: 100%;
.arrs {
width: 100%;
.arrs-items {
margin: 40rpx 0 0 0;
display: flex;
.left {
flex-shrink: 0;
margin-right: 12rpx;
@@ -139,70 +493,71 @@
height: 44rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 8rpx;
border: 1rpx solid #999999;
font-size: 32rpx;
}
.right {
flex-grow: 1;
.r-title {
font-size: 32rpx;
height: 44rpx;
display: flex;
align-items: center;
.num {
font-size: 34rpx;
}
}
.r-box {
padding: 21rpx 0 0 0;
display: flex;
flex-wrap: wrap;
.r-box-item {
margin-right: 24rpx;
}
.r-box-item-lang {
margin-top: 19rpx;
width: 100%;
display: flex;
align-items: center;
.contrast {
margin: 0 0 0 24rpx;
display: flex;
align-items: center;
}
.down {
color: #43CD80;
font-size: 34rpx;
}
.up {
font-size: 34rpx;
color: #E7483C;
}
}
}
.ranking {
padding: 21rpx 0 0 0;
display: flex;
flex-direction: column;
.ranking-item {
margin-bottom: 22rpx;
display: flex;
align-items: center;
font-size: 30rpx;
.serial {
flex-shrink: 0;
width: 42rpx;
@@ -214,24 +569,67 @@
align-items: center;
color: #fff;
}
.lside {
margin: 0 20rpx;
color: #505050;
}
.rside {
flex-shrink: 0;
font-size: 32rpx;
}
}
}
}
}
}
}
}

.nav-footer {
margin: 32rpx 0;
width: 100%;
display: flex;
justify-content: center;

.footer-item {
width: 334rpx;
height: 88rpx;
display: flex;
justify-content: center;
align-items: center;
color: #2671E2;
border: 2rpx solid #2671E2;
border-radius: 8rpx;
overflow: hidden;
font-size: 32rpx;

&.full {
background: #2671E2;
color: #fff;

.fulls {
width: 100%;
height: 100%;
background: transparent;
color: #fff;
}
}
}

}


.empty {
width: 100%;
height: 240rpx;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
}
</style>
</style>

+ 513
- 150
pages/mine/reportExcel/weekReport.vue
File diff suppressed because it is too large
View File


+ 152
- 0
static/libs/image-tools.js View File

@@ -0,0 +1,152 @@
function getLocalFilePath(path) {
if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf('_downloads') === 0) {
return path
}
if (path.indexOf('file://') === 0) {
return path
}
if (path.indexOf('/storage/emulated/0/') === 0) {
return path
}
if (path.indexOf('/') === 0) {
var localFilePath = plus.io.convertAbsoluteFileSystem(path)
if (localFilePath !== path) {
return localFilePath
} else {
path = path.substr(1)
}
}
return '_www/' + path
}

export function pathToBase64(path) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
if (typeof FileReader === 'function') {
var xhr = new XMLHttpRequest()
xhr.open('GET', path, true)
xhr.responseType = 'blob'
xhr.onload = function() {
if (this.status === 200) {
let fileReader = new FileReader()
fileReader.onload = function(e) {
resolve(e.target.result)
}
fileReader.onerror = reject
fileReader.readAsDataURL(this.response)
}
}
xhr.onerror = reject
xhr.send()
return
}
var canvas = document.createElement('canvas')
var c2x = canvas.getContext('2d')
var img = new Image
img.onload = function() {
canvas.width = img.width
canvas.height = img.height
c2x.drawImage(img, 0, 0)
resolve(canvas.toDataURL())
canvas.height = canvas.width = 0
}
img.onerror = reject
img.src = path
return
}
if (typeof plus === 'object') {
plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) {
entry.file(function(file) {
var fileReader = new plus.io.FileReader()
fileReader.onload = function(data) {
resolve(data.target.result)
}
fileReader.onerror = function(error) {
reject(error)
}
fileReader.readAsDataURL(file)
}, function(error) {
reject(error)
})
}, function(error) {
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
wx.getFileSystemManager().readFile({
filePath: path,
encoding: 'base64',
success: function(res) {
resolve('data:image/png;base64,' + res.data)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}

export function base64ToPath(base64, extName) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
base64 = base64.split(',')
var type = base64[0].match(/:(.*?);/)[1]
var str = atob(base64[1])
var n = str.length
var array = new Uint8Array(n)
while (n--) {
array[n] = str.charCodeAt(n)
}
return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { type: type })))
}
var fileName;
if (!extName) {
extName = base64.match(/data\:\S+\/(\S+);/)
if (extName) {
extName = extName[1]
} else {
reject(new Error('base64 error'))
}
fileName = Date.now() + '.' + extName;
} else {
fileName = Date.now() + extName;
}
if (typeof plus === 'object') {
var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
bitmap.loadBase64Data(base64, function() {
var filePath = '_doc/uniapp_temp/' + fileName
bitmap.save(filePath, {}, function() {
bitmap.clear()
resolve(filePath)
}, function(error) {
bitmap.clear()
reject(error)
})
}, function(error) {
bitmap.clear()
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
var filePath = wx.env.USER_DATA_PATH + '/' + fileName
wx.getFileSystemManager().writeFile({
filePath: filePath,
data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
encoding: 'base64',
success: function() {
resolve(filePath)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}

+ 7
- 0
store/index.js View File

@@ -6,9 +6,16 @@ Vue.use(Vuex)
export default new Vuex.Store({
state: {
bgAudioMannager: null,
messageObj: {} , // 用户信息
},
mutations: {
// 日报详情
setMessageObj(state, obj) {
state.messageObj = obj
},
createAudio(state) {
state.bgAudioMannager = uni.getBackgroundAudioManager();
},


+ 1
- 12
utils/domain.js View File

@@ -1,17 +1,6 @@
// http.js使用域名
// const baseUrl = 'http://192.168.31.57:8080/autoSR/api';// 本地
// const baseUrl = 'http://127.0.0.1:8080/api';// 本地
// const baseUrl = 'http://121.42.63.138:9091/autoSR/api';// 测试站
// const baseUrl = 'http://192.168.31.89:9090/api';// sh
// const baseUrl = 'http://121.42.63.138:9091/autoSR/api';// 测试站
// const baseUrl = 'http://192.168.31.92:8080/api';// 测试站
// const baseUrl = 'http://127.0.0.1:8080/autoSR/api';// 本地
// const baseUrl = 'http://192.168.31.244:8080/autoSR/api';// 本地
const baseUrl = 'http://81.70.55.170:9090/autoSR/api';// 测试站
const baseUrl = 'http://81.70.55.170:9090/autoSR/api';// 最新测试
// const baseUrl = 'http://192.168.31.210:8080/api'; // 泽明
// const baseUrl = 'http://192.168.31.167:8080/autoSR/api'; // 长龙
// const baseUrl = 'http://192.168.31.134:8080/autoSR/api'; // 佳豪
// const baseUrl = 'http://10.2.1.104:8081/autoSR/api'; // 刘敏
// const baseUrl = 'https://zkgj.quhouse.com/api'; // 质控正式
// const baseUrl = 'https://hfju.com/api'; // 数智正式



Loading…
Cancel
Save