@@ -4,11 +4,23 @@ | |||
"configurations": [{ | |||
"default" : | |||
{ | |||
<<<<<<< HEAD | |||
"launchtype" : "local" | |||
}, | |||
"mp-weixin" : | |||
{ | |||
"launchtype" : "local" | |||
======= | |||
"launchtype" : "remote" | |||
}, | |||
"h5" : | |||
{ | |||
"launchtype" : "remote" | |||
}, | |||
"mp-weixin" : | |||
{ | |||
"launchtype" : "remote" | |||
>>>>>>> dev | |||
}, | |||
"type" : "uniCloud" | |||
} | |||
@@ -0,0 +1,425 @@ | |||
<script> | |||
import Vue from 'vue' | |||
//app.js | |||
var config = require("./config"); | |||
export default { | |||
onLaunch(options) { | |||
uni.getSystemInfo({ | |||
success: function(e) { | |||
console.log(e, 'adjsakljdklasjdklsakjdslakjd') | |||
// #ifdef MP-WEIXIN | |||
Vue.prototype.StatusBar = e.statusBarHeight; | |||
let custom = wx.getMenuButtonBoundingClientRect(); | |||
Vue.prototype.Custom = custom; | |||
Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight; | |||
Vue.prototype.windowHeight = e.safeArea.height | |||
// #endif | |||
Vue.mixin({ | |||
data() { | |||
return { | |||
StatusBar: Vue.prototype.StatusBar, | |||
CustomBar: Vue.prototype.CustomBar, | |||
windowHeight: Vue.prototype.windowHeight | |||
}; | |||
}, | |||
methods: { | |||
// 时分秒转换为秒 | |||
TIMEEVENT(e) { | |||
var time = e; | |||
var len = time.split(':') | |||
if (len.length == 3) { | |||
var hour = time.split(':')[0]; | |||
var min = time.split(':')[1]; | |||
var sec = time.split(':')[2]; | |||
return Number(hour * 3600) + Number(min * 60) + Number(sec); | |||
} | |||
if (len.length == 2) { | |||
var min = time.split(':')[0]; | |||
var sec = time.split(':')[1]; | |||
return Number(min * 60) + Number(sec); | |||
} | |||
if (len.length == 1) { | |||
var sec = time.split(':')[0]; | |||
return Number(sec); | |||
} | |||
}, | |||
// 目前使用页面为录音页面 | |||
SPEAKERSTYLE(index) { | |||
let obj = { | |||
color: '', | |||
} | |||
switch (index) { | |||
case 1: | |||
obj.color = '#60CBEC'; | |||
break; | |||
case 2: | |||
obj.color = '#EC8B47'; | |||
break; | |||
case 3: | |||
obj.color = '#4F861E'; | |||
break; | |||
case 5: | |||
obj.color = '#4980C8'; | |||
break; | |||
case 6: | |||
obj.color = '#60CBEC'; | |||
break; | |||
case 7: | |||
obj.color = '#EC8B47'; | |||
break; | |||
case 8: | |||
obj.color = '#4F861E'; | |||
break; | |||
default: | |||
obj.color = '#9F61C8'; | |||
break; | |||
} | |||
return obj | |||
}, | |||
}, | |||
filters: { | |||
// ASCII码转换 大写字母A是65 演讲人是从1开始所以num+64 | |||
toCapital(num) { | |||
let str = '' | |||
if (num) { | |||
str = String.fromCharCode(num + 64) | |||
} | |||
return str | |||
} | |||
} | |||
}); | |||
} | |||
}); | |||
if (wx.canIUse('getUpdateManager')) { | |||
const updateManager = wx.getUpdateManager() | |||
updateManager.onCheckForUpdate(function(res) { | |||
if (res.hasUpdate) { | |||
updateManager.onUpdateReady(function() { | |||
uni.showModal({ | |||
title: '更新提示', | |||
cancelColor: "#999999", | |||
content: '新版本已经准备好,是否重启应用?', | |||
success: function(res) { | |||
if (res.confirm) { | |||
updateManager.applyUpdate() | |||
} | |||
} | |||
}) | |||
}) | |||
updateManager.onUpdateFailed(function() { | |||
uni.showModal({ | |||
title: '已经有新版本了哟~', | |||
cancelColor: "#999999", | |||
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~' | |||
}) | |||
}) | |||
} | |||
}) | |||
} else { | |||
uni.showModal({ | |||
title: '提示', | |||
cancelColor: "#999999", | |||
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。' | |||
}) | |||
} | |||
const token = uni.getStorageSync("weapp_session_login_data") | |||
if (typeof token.token != "string") { | |||
return | |||
} | |||
this.$u.get("/user/getUser").then(data => { | |||
uni.setStorageSync("weapp_session_userInfo_data", data) | |||
}) | |||
this.$u.get("/user/getMenu").then(data => { | |||
uni.setStorageSync("weapp_session_Menu_data", data) | |||
}) | |||
wx.setInnerAudioOption({ | |||
obeyMuteSwitch: false | |||
}); | |||
}, | |||
onShow(options) { | |||
const token = uni.getStorageSync("weapp_session_login_data") | |||
if (typeof token.token != "string") { | |||
console.log("没有") | |||
return | |||
} else { | |||
this.infoscoket() | |||
} | |||
}, | |||
onHide() {}, | |||
methods: { | |||
infoscoket() { | |||
let pushon = uni.getStorageSync('weapp_session_userInfo_data').loginName | |||
uni.connectSocket({ | |||
url: 'wss://hfju.com/ws?uid=' + pushon + '_applets', | |||
header: { | |||
"content-type": "application/json", | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
} | |||
}); | |||
uni.onSocketOpen(function(res) { | |||
console.log('WebSocket连接已打开!'); | |||
}); | |||
uni.onSocketError(function(res) { | |||
console.log('WebSocket连接打开失败,请检查!'); | |||
}); | |||
uni.onSocketMessage(function(res) { | |||
console.log('收到服务器内容:' + res.data); | |||
let cedata = JSON.stringify(res); | |||
let data = JSON.parse(cedata); | |||
let zdata = JSON.parse(data.data) | |||
if (zdata.to == "recCmd") { | |||
uni.$emit('update', { | |||
msg: '页面更新' | |||
}) | |||
return | |||
} | |||
uni.showModal({ | |||
title: '提示', | |||
content: zdata.to + '的设备电量过低请检查!', | |||
cancelText: "取消", // 取消按钮的文字 | |||
confirmText: "查看", // 确认按钮文字 | |||
success: function(res) { | |||
if (res.confirm) { | |||
console.log('用户点击确定'); | |||
uni.navigateTo({ | |||
url: `/pages/main/toviewtherecording/index?jump=` + "jump" | |||
}) | |||
} else if (res.cancel) { | |||
console.log('用户点击取消'); | |||
} | |||
} | |||
}); | |||
}); | |||
}, | |||
Closewebsocke() { | |||
uni.closeSocket(); | |||
uni.onSocketClose(function(res) { | |||
console.log('WebSocket 已关闭!'); | |||
}); | |||
}, | |||
} | |||
}; | |||
</script> | |||
<style> | |||
@import "./app.css"; | |||
</style> | |||
<style lang="scss"> | |||
@import "uview-ui/index.scss"; | |||
/*每个页面公共css */ | |||
//图表样式等 | |||
.single { | |||
width: 100%; | |||
background: #FFFFFF; | |||
.title { | |||
width: 100%; | |||
height: 90rpx; | |||
border-bottom: 1rpx solid #E0E0E0; | |||
display: flex; | |||
.title1 { | |||
flex: 2; | |||
font-size: 30rpx; | |||
font-weight: 600; | |||
color: #333333; | |||
line-height: 90rpx; | |||
text-indent: 30rpx; | |||
} | |||
.title3 { | |||
flex: 3; | |||
height: 90rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: flex-end; | |||
.title3-box { | |||
display: flex; | |||
align-items: center; | |||
width: 25%; | |||
justify-content: center; | |||
.activecltab { | |||
border-bottom: 2px solid #2671E2; | |||
} | |||
} | |||
} | |||
.title2 { | |||
flex: 3; | |||
height: 90rpx; | |||
display: flex; | |||
align-items: center; | |||
.title2-che { | |||
width: 178rpx; | |||
height: 48rpx; | |||
background: #FFFFFF; | |||
border-radius: 6rpx; | |||
border: 1px solid #E0E0E0; | |||
line-height: 48rpx; | |||
font-size: 28rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
text-indent: 12rpx; | |||
margin-left: 35rpx; | |||
position: relative; | |||
.righttochoose { | |||
width: 18rpx; | |||
height: 24rpx; | |||
position: absolute; | |||
top: 12rpx; | |||
right: 12rpx; | |||
} | |||
} | |||
} | |||
} | |||
.swiper-box { | |||
width: 97%; | |||
margin: 0 auto; | |||
} | |||
.hejibox { | |||
width: 100%; | |||
height: 80rpx; | |||
display: flex; | |||
.heji { | |||
width: 50%; | |||
height: 100%; | |||
font-size: 28rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
line-height: 80rpx; | |||
text-indent: 30rpx; | |||
} | |||
} | |||
.danwei { | |||
width: 100%; | |||
height: 40rpx; | |||
font-size: 24rpx; | |||
font-weight: 400; | |||
color: #999999; | |||
line-height: 40rpx; | |||
text-indent: 30rpx; | |||
} | |||
.uchaserbox { | |||
width: 95%; | |||
height: 470rpx; | |||
} | |||
.jindu { | |||
width: 100%; | |||
height: 300rpx; | |||
.jindu-box { | |||
width: 100%; | |||
padding-left: 30rpx; | |||
padding-right: 30rpx; | |||
.jindu-boxche { | |||
width: 100%; | |||
height: 46rpx; | |||
display: flex; | |||
align-items: center; | |||
height: 50rpx; | |||
.jindu-name { | |||
width: 120rpx; | |||
font-size: 28rpx; | |||
color: #666666; | |||
} | |||
.jindu-zxl { | |||
width: 120rpx; | |||
font-size: 26rpx; | |||
margin-left: 16rpx; | |||
color: #666666; | |||
text-align: center; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
//时间切换的样式 | |||
.boxtittab { | |||
width: 100; | |||
height: 92rpx; | |||
background: #FFFFFF; | |||
border: 1px solid #E0E0E0; | |||
display: flex; | |||
align-items: center; | |||
.tabbox { | |||
flex: 1; | |||
height: 100%; | |||
text-align: center; | |||
line-height: 92rpx; | |||
color: #666666; | |||
font-size: 28rpx; | |||
display: flex; | |||
justify-content: center; | |||
.activecllasscet { | |||
width: 96rpx; | |||
border-bottom: 2px solid #2671E2; | |||
} | |||
} | |||
} | |||
//多个格子的样式 | |||
.boxzonglan { | |||
width: 100%; | |||
min-height: 496rpx; | |||
background: #FFFFFF; | |||
padding: 30rpx 30rpx 30rpx 30rpx; | |||
.zonglantit { | |||
font-size: 30rpx; | |||
color: #333333; | |||
font-family: PingFangSC-Semibold, PingFang SC; | |||
font-weight: 600; | |||
} | |||
.zonglanbox { | |||
width: 100%; | |||
display: flex; | |||
flex-wrap: wrap; | |||
margin-top: 24rpx; | |||
.grid { | |||
width: 50%; | |||
height: 128rpx; | |||
border: 1px solid #E0E0E0; | |||
.audonum { | |||
color: #666666; | |||
text-indent: 40rpx; | |||
font-size: 26rpx; | |||
margin-top: 20rpx; | |||
} | |||
.num { | |||
color: #333333; | |||
text-indent: 40rpx; | |||
font-size: 32rpx; | |||
font-weight: 600; | |||
margin-top: 10rpx; | |||
} | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,28 @@ | |||
<template> | |||
<!-- '<audio/>' 组件不再维护,建议使用能力更强的 'uni.createInnerAudioContext' 接口 有时间再改--> | |||
<!--增加audio标签支持--> | |||
<audio | |||
:id="node.attr.id" | |||
:class="node.classStr" | |||
:style="node.styleStr" | |||
:src="node.attr.src" | |||
:loop="node.attr.loop" | |||
:poster="node.attr.poster" | |||
:name="node.attr.name" | |||
:author="node.attr.author" | |||
controls></audio> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseAudio', | |||
props: { | |||
node: { | |||
type: Object, | |||
default() { | |||
return {}; | |||
}, | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -0,0 +1,94 @@ | |||
<template> | |||
<image | |||
:mode="node.attr.mode" | |||
:lazy-load="node.attr.lazyLoad" | |||
:class="node.classStr" | |||
:style="newStyleStr || node.styleStr" | |||
:data-src="node.attr.src" | |||
:src="node.attr.src" | |||
@tap="wxParseImgTap" | |||
@load="wxParseImgLoad" | |||
/> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseImg', | |||
data() { | |||
return { | |||
newStyleStr: '', | |||
preview: true | |||
}; | |||
}, | |||
inject: ['parseWidth'], | |||
mounted() {}, | |||
props: { | |||
node: { | |||
type: Object, | |||
default() { | |||
return {}; | |||
} | |||
} | |||
}, | |||
methods: { | |||
wxParseImgTap(e) { | |||
if (!this.preview) return; | |||
const { src } = e.currentTarget.dataset; | |||
if (!src) return; | |||
let parent = this.$parent; | |||
while (!parent.preview || typeof parent.preview !== 'function') { | |||
// TODO 遍历获取父节点执行方法 | |||
parent = parent.$parent; | |||
} | |||
parent.preview(src, e); | |||
}, | |||
// 图片视觉宽高计算函数区 | |||
wxParseImgLoad(e) { | |||
const { src } = e.currentTarget.dataset; | |||
if (!src) return; | |||
let { width, height } = e.mp.detail; | |||
const recal = this.wxAutoImageCal(width, height); | |||
const { imageheight, imageWidth } = recal; | |||
const { padding, mode } = this.node.attr;//删除padding | |||
// const { mode } = this.node.attr; | |||
const { styleStr } = this.node; | |||
const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`; | |||
this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;//删除padding | |||
// this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px;`; | |||
}, | |||
// 计算视觉优先的图片宽高 | |||
wxAutoImageCal(originalWidth, originalHeight) { | |||
// 获取图片的原始长宽 | |||
const windowWidth = this.parseWidth.value; | |||
const results = {}; | |||
if (originalWidth < 60 || originalHeight < 60) { | |||
const { src } = this.node.attr; | |||
let parent = this.$parent; | |||
while (!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.removeImageUrl(src); | |||
this.preview = false; | |||
} | |||
// 判断按照那种方式进行缩放 | |||
if (originalWidth > windowWidth) { | |||
// 在图片width大于手机屏幕width时候 | |||
results.imageWidth = windowWidth; | |||
results.imageheight = windowWidth * (originalHeight / originalWidth); | |||
} else { | |||
// 否则展示原来的数据 | |||
results.imageWidth = originalWidth; | |||
results.imageheight = originalHeight; | |||
} | |||
return results; | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,55 @@ | |||
<template> | |||
<div class='tablebox'> | |||
<rich-text :nodes="nodes" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseTable', | |||
props: { | |||
node: { | |||
type: Object, | |||
default() { | |||
return {}; | |||
}, | |||
}, | |||
}, | |||
inject: ['parseSelect'], | |||
data() { | |||
return { | |||
nodes:[] | |||
}; | |||
}, | |||
mounted() { | |||
this.nodes=this.loadNode([this.node]); | |||
}, | |||
methods: { | |||
loadNode(node) { | |||
let obj = []; | |||
for (let children of node) { | |||
if (children.node=='element') { | |||
let t = { | |||
name:children.tag, | |||
attrs: { | |||
class: children.classStr, | |||
// style: children.styleStr, | |||
}, | |||
children: children.nodes?this.loadNode(children.nodes):[] | |||
} | |||
obj.push(t) | |||
} else if(children.node=='text'){ | |||
obj.push({ | |||
type: 'text', | |||
text: children.text | |||
}) | |||
} | |||
} | |||
return obj | |||
} | |||
} | |||
}; | |||
</script> | |||
<style> | |||
@import url("../parse.css"); | |||
</style> |
@@ -0,0 +1,98 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node"/> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text'">{{node.text}}</block> | |||
</template> | |||
<script> | |||
// #ifdef APP-PLUS | H5 | |||
import wxParseTemplate from './wxParseTemplate0'; | |||
// #endif | |||
// #ifdef MP | |||
import wxParseTemplate from './wxParseTemplate1'; | |||
// #endif | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
// #ifdef APP-PLUS | H5 | |||
name: 'wxParseTemplate', | |||
// #endif | |||
// #ifdef MP | |||
name: 'wxParseTemplate0', | |||
// #endif | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset;// TODO currentTarget才有dataset | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法 | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text'">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate2'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate1', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate11'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate10', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,86 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate11', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text'">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate3'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate2', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate4'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate3', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate5'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate4', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate6'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate5', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate7'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate6', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate8'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate7', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate9'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate8', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<!--判断是否是标签节点--> | |||
<block v-if="node.node == 'element'"> | |||
<!--button类型--> | |||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr"> | |||
<wx-parse-template :node="node" /> | |||
</button> | |||
<!--a类型--> | |||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--li类型--> | |||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
<!--table类型--> | |||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" /> | |||
<!--br类型--> | |||
<!-- #ifndef H5 --> | |||
<text v-else-if="node.tag == 'br'">\n</text> | |||
<!-- #endif --> | |||
<!-- #ifdef H5 --> | |||
<br v-else-if="node.tag == 'br'"> | |||
<!-- #endif --> | |||
<!--video类型--> | |||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/> | |||
<!--audio类型--> | |||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/> | |||
<!--img类型--> | |||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/> | |||
<!--其他标签--> | |||
<view v-else :class="node.classStr" :style="node.styleStr"> | |||
<block v-for="(node, index) of node.nodes" :key="index"> | |||
<wx-parse-template :node="node" /> | |||
</block> | |||
</view> | |||
</block> | |||
<!--判断是否是文本节点--> | |||
<block v-else-if="node.node == 'text' ">{{node.text}}</block> | |||
</template> | |||
<script> | |||
import wxParseTemplate from './wxParseTemplate10'; | |||
import wxParseImg from './wxParseImg'; | |||
import wxParseVideo from './wxParseVideo'; | |||
import wxParseAudio from './wxParseAudio'; | |||
import wxParseTable from './wxParseTable'; | |||
export default { | |||
name: 'wxParseTemplate9', | |||
props: { | |||
node: {}, | |||
}, | |||
components: { | |||
wxParseTemplate, | |||
wxParseImg, | |||
wxParseVideo, | |||
wxParseAudio, | |||
wxParseTable | |||
}, | |||
methods: { | |||
wxParseATap(attr,e) { | |||
const { | |||
href | |||
} = e.currentTarget.dataset; | |||
if (!href) return; | |||
let parent = this.$parent; | |||
while(!parent.preview || typeof parent.preview !== 'function') { | |||
parent = parent.$parent; | |||
} | |||
parent.navigate(href, e, attr); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,15 @@ | |||
<template> | |||
<!--增加video标签支持,并循环添加--> | |||
<view :class="node.classStr" :style="node.styleStr"> | |||
<video :class="node.classStr" :style="node.styleStr" class="video-video" :src="node.attr.src"></video> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'wxParseVideo', | |||
props: { | |||
node: {}, | |||
}, | |||
}; | |||
</script> |
@@ -0,0 +1,261 @@ | |||
/** | |||
* html2Json 改造来自: https://github.com/Jxck/html2json | |||
* | |||
* | |||
* author: Di (微信小程序开发工程师) | |||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | |||
* 垂直微信小程序开发交流社区 | |||
* | |||
* github地址: https://github.com/icindy/wxParse | |||
* | |||
* for: 微信小程序富文本解析 | |||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | |||
*/ | |||
import wxDiscode from './wxDiscode'; | |||
import HTMLParser from './htmlparser'; | |||
function makeMap(str) { | |||
const obj = {}; | |||
const items = str.split(','); | |||
for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; | |||
return obj; | |||
} | |||
// Block Elements - HTML 5 | |||
const block = makeMap('br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); | |||
// Inline Elements - HTML 5 | |||
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); | |||
// Elements that you can, intentionally, leave open | |||
// (and which close themselves) | |||
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); | |||
function removeDOCTYPE(html) { | |||
const isDocument = /<body.*>([^]*)<\/body>/.test(html); | |||
return isDocument ? RegExp.$1 : html; | |||
} | |||
function trimHtml(html) { | |||
return html | |||
.replace(/<!--.*?-->/gi, '') | |||
.replace(/\/\*.*?\*\//gi, '') | |||
.replace(/[ ]+</gi, '<') | |||
.replace(/<script[^]*<\/script>/gi, '') | |||
.replace(/<style[^]*<\/style>/gi, ''); | |||
} | |||
function getScreenInfo() { | |||
const screen = {}; | |||
wx.getSystemInfo({ | |||
success: (res) => { | |||
screen.width = res.windowWidth; | |||
screen.height = res.windowHeight; | |||
}, | |||
}); | |||
return screen; | |||
} | |||
function html2json(html, customHandler, imageProp, host) { | |||
// 处理字符串 | |||
html = removeDOCTYPE(html); | |||
html = trimHtml(html); | |||
html = wxDiscode.strDiscode(html); | |||
// 生成node节点 | |||
const bufArray = []; | |||
const results = { | |||
nodes: [], | |||
imageUrls: [], | |||
}; | |||
const screen = getScreenInfo(); | |||
function Node(tag) { | |||
this.node = 'element'; | |||
this.tag = tag; | |||
this.$screen = screen; | |||
} | |||
HTMLParser(html, { | |||
start(tag, attrs, unary) { | |||
// node for this element | |||
const node = new Node(tag); | |||
if (bufArray.length !== 0) { | |||
const parent = bufArray[0]; | |||
if (parent.nodes === undefined) { | |||
parent.nodes = []; | |||
} | |||
} | |||
if (block[tag]) { | |||
node.tagType = 'block'; | |||
} else if (inline[tag]) { | |||
node.tagType = 'inline'; | |||
} else if (closeSelf[tag]) { | |||
node.tagType = 'closeSelf'; | |||
} | |||
node.attr = attrs.reduce((pre, attr) => { | |||
const { name } = attr; | |||
let { value } = attr; | |||
if (name === 'class') { | |||
node.classStr = value; | |||
} | |||
// has multi attibutes | |||
// make it array of attribute | |||
if (name === 'style') { | |||
node.styleStr = value; | |||
} | |||
if (value.match(/ /)) { | |||
value = value.split(' '); | |||
} | |||
// if attr already exists | |||
// merge it | |||
if (pre[name]) { | |||
if (Array.isArray(pre[name])) { | |||
// already array, push to last | |||
pre[name].push(value); | |||
} else { | |||
// single value, make it array | |||
pre[name] = [pre[name], value]; | |||
} | |||
} else { | |||
// not exist, put it | |||
pre[name] = value; | |||
} | |||
return pre; | |||
}, {}); | |||
// 优化样式相关属性 | |||
if (node.classStr) { | |||
node.classStr += ` ${node.tag}`; | |||
} else { | |||
node.classStr = node.tag; | |||
} | |||
if (node.tagType === 'inline') { | |||
node.classStr += ' inline'; | |||
} | |||
// 对img添加额外数据 | |||
if (node.tag === 'img') { | |||
let imgUrl = node.attr.src; | |||
imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain); | |||
Object.assign(node.attr, imageProp, { | |||
src: imgUrl || '', | |||
}); | |||
if (imgUrl) { | |||
results.imageUrls.push(imgUrl); | |||
} | |||
} | |||
// 处理a标签属性 | |||
if (node.tag === 'a') { | |||
node.attr.href = node.attr.href || ''; | |||
} | |||
// 处理font标签样式属性 | |||
if (node.tag === 'font') { | |||
const fontSize = [ | |||
'x-small', | |||
'small', | |||
'medium', | |||
'large', | |||
'x-large', | |||
'xx-large', | |||
'-webkit-xxx-large', | |||
]; | |||
const styleAttrs = { | |||
color: 'color', | |||
face: 'font-family', | |||
size: 'font-size', | |||
}; | |||
if (!node.styleStr) node.styleStr = ''; | |||
Object.keys(styleAttrs).forEach((key) => { | |||
if (node.attr[key]) { | |||
const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key]; | |||
node.styleStr += `${styleAttrs[key]}: ${value};`; | |||
} | |||
}); | |||
} | |||
// 临时记录source资源 | |||
if (node.tag === 'source') { | |||
results.source = node.attr.src; | |||
} | |||
if (customHandler.start) { | |||
customHandler.start(node, results); | |||
} | |||
if (unary) { | |||
// if this tag doesn't have end tag | |||
// like <img src="hoge.png"/> | |||
// add to parents | |||
const parent = bufArray[0] || results; | |||
if (parent.nodes === undefined) { | |||
parent.nodes = []; | |||
} | |||
parent.nodes.push(node); | |||
} else { | |||
bufArray.unshift(node); | |||
} | |||
}, | |||
end(tag) { | |||
// merge into parent tag | |||
const node = bufArray.shift(); | |||
if (node.tag !== tag) { | |||
console.error('invalid state: mismatch end tag'); | |||
} | |||
// 当有缓存source资源时于于video补上src资源 | |||
if (node.tag === 'video' && results.source) { | |||
node.attr.src = results.source; | |||
delete results.source; | |||
} | |||
if (customHandler.end) { | |||
customHandler.end(node, results); | |||
} | |||
if (bufArray.length === 0) { | |||
results.nodes.push(node); | |||
} else { | |||
const parent = bufArray[0]; | |||
if (!parent.nodes) { | |||
parent.nodes = []; | |||
} | |||
parent.nodes.push(node); | |||
} | |||
}, | |||
chars(text) { | |||
if (!text.trim()) return; | |||
const node = { | |||
node: 'text', | |||
text, | |||
}; | |||
if (customHandler.chars) { | |||
customHandler.chars(node, results); | |||
} | |||
if (bufArray.length === 0) { | |||
results.nodes.push(node); | |||
} else { | |||
const parent = bufArray[0]; | |||
if (parent.nodes === undefined) { | |||
parent.nodes = []; | |||
} | |||
parent.nodes.push(node); | |||
} | |||
}, | |||
}); | |||
return results; | |||
} | |||
export default html2json; |
@@ -0,0 +1,156 @@ | |||
/** | |||
* | |||
* htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser | |||
* | |||
* author: Di (微信小程序开发工程师) | |||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | |||
* 垂直微信小程序开发交流社区 | |||
* | |||
* github地址: https://github.com/icindy/wxParse | |||
* | |||
* for: 微信小程序富文本解析 | |||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | |||
*/ | |||
// Regular Expressions for parsing tags and attributes | |||
const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; | |||
const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; | |||
const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; | |||
function makeMap(str) { | |||
const obj = {}; | |||
const items = str.split(','); | |||
for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; | |||
return obj; | |||
} | |||
// Empty Elements - HTML 5 | |||
const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); | |||
// Block Elements - HTML 5 | |||
const block = makeMap('address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); | |||
// Inline Elements - HTML 5 | |||
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); | |||
// Elements that you can, intentionally, leave open | |||
// (and which close themselves) | |||
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); | |||
// Attributes that have their values filled in disabled="disabled" | |||
const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); | |||
function HTMLParser(html, handler) { | |||
let index; | |||
let chars; | |||
let match; | |||
let last = html; | |||
const stack = []; | |||
stack.last = () => stack[stack.length - 1]; | |||
function parseEndTag(tag, tagName) { | |||
// If no tag name is provided, clean shop | |||
let pos; | |||
if (!tagName) { | |||
pos = 0; | |||
} else { | |||
// Find the closest opened tag of the same type | |||
tagName = tagName.toLowerCase(); | |||
for (pos = stack.length - 1; pos >= 0; pos -= 1) { | |||
if (stack[pos] === tagName) break; | |||
} | |||
} | |||
if (pos >= 0) { | |||
// Close all the open elements, up the stack | |||
for (let i = stack.length - 1; i >= pos; i -= 1) { | |||
if (handler.end) handler.end(stack[i]); | |||
} | |||
// Remove the open elements from the stack | |||
stack.length = pos; | |||
} | |||
} | |||
function parseStartTag(tag, tagName, rest, unary) { | |||
tagName = tagName.toLowerCase(); | |||
if (block[tagName]) { | |||
while (stack.last() && inline[stack.last()]) { | |||
parseEndTag('', stack.last()); | |||
} | |||
} | |||
if (closeSelf[tagName] && stack.last() === tagName) { | |||
parseEndTag('', tagName); | |||
} | |||
unary = empty[tagName] || !!unary; | |||
if (!unary) stack.push(tagName); | |||
if (handler.start) { | |||
const attrs = []; | |||
rest.replace(attr, function genAttr(matches, name) { | |||
const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : ''); | |||
attrs.push({ | |||
name, | |||
value, | |||
escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // " | |||
}); | |||
}); | |||
if (handler.start) { | |||
handler.start(tagName, attrs, unary); | |||
} | |||
} | |||
} | |||
while (html) { | |||
chars = true; | |||
if (html.indexOf('</') === 0) { | |||
match = html.match(endTag); | |||
if (match) { | |||
html = html.substring(match[0].length); | |||
match[0].replace(endTag, parseEndTag); | |||
chars = false; | |||
} | |||
// start tag | |||
} else if (html.indexOf('<') === 0) { | |||
match = html.match(startTag); | |||
if (match) { | |||
html = html.substring(match[0].length); | |||
match[0].replace(startTag, parseStartTag); | |||
chars = false; | |||
} | |||
} | |||
if (chars) { | |||
index = html.indexOf('<'); | |||
let text = ''; | |||
while (index === 0) { | |||
text += '<'; | |||
html = html.substring(1); | |||
index = html.indexOf('<'); | |||
} | |||
text += index < 0 ? html : html.substring(0, index); | |||
html = index < 0 ? '' : html.substring(index); | |||
if (handler.chars) handler.chars(text); | |||
} | |||
if (html === last) throw new Error(`Parse Error: ${html}`); | |||
last = html; | |||
} | |||
// Clean up any remaining tags | |||
parseEndTag(); | |||
} | |||
export default HTMLParser; |
@@ -0,0 +1,209 @@ | |||
// HTML 支持的数学符号 | |||
function strNumDiscode(str) { | |||
str = str.replace(/∀|∀|∀/g, '∀'); | |||
str = str.replace(/∂|∂|∂/g, '∂'); | |||
str = str.replace(/∃|∃|∃/g, '∃'); | |||
str = str.replace(/∅|∅|∅/g, '∅'); | |||
str = str.replace(/∇|∇|∇/g, '∇'); | |||
str = str.replace(/∈|∈|∈/g, '∈'); | |||
str = str.replace(/∉|∉|∉/g, '∉'); | |||
str = str.replace(/∋|∋|∋/g, '∋'); | |||
str = str.replace(/∏|∏|∏/g, '∏'); | |||
str = str.replace(/∑|∑|∑/g, '∑'); | |||
str = str.replace(/−|−|−/g, '−'); | |||
str = str.replace(/∗|∗|∗/g, '∗'); | |||
str = str.replace(/√|√|√/g, '√'); | |||
str = str.replace(/∝|∝|∝/g, '∝'); | |||
str = str.replace(/∞|∞|∞/g, '∞'); | |||
str = str.replace(/∠|∠|∠/g, '∠'); | |||
str = str.replace(/∧|∧|∧/g, '∧'); | |||
str = str.replace(/∨|∨|∨/g, '∨'); | |||
str = str.replace(/∩|∩|∩/g, '∩'); | |||
str = str.replace(/∪|∪|∪/g, '∪'); | |||
str = str.replace(/∫|∫|∫/g, '∫'); | |||
str = str.replace(/∴|∴|∴/g, '∴'); | |||
str = str.replace(/∼|∼|∼/g, '∼'); | |||
str = str.replace(/≅|≅|≅/g, '≅'); | |||
str = str.replace(/≈|≈|≈/g, '≈'); | |||
str = str.replace(/≠|≠|≠/g, '≠'); | |||
str = str.replace(/≤|≤|≤/g, '≤'); | |||
str = str.replace(/≥|≥|≥/g, '≥'); | |||
str = str.replace(/⊂|⊂|⊂/g, '⊂'); | |||
str = str.replace(/⊃|⊃|⊃/g, '⊃'); | |||
str = str.replace(/⊄|⊄|⊄/g, '⊄'); | |||
str = str.replace(/⊆|⊆|⊆/g, '⊆'); | |||
str = str.replace(/⊇|⊇|⊇/g, '⊇'); | |||
str = str.replace(/⊕|⊕|⊕/g, '⊕'); | |||
str = str.replace(/⊗|⊗|⊗/g, '⊗'); | |||
str = str.replace(/⊥|⊥|⊥/g, '⊥'); | |||
str = str.replace(/⋅|⋅|⋅/g, '⋅'); | |||
return str; | |||
} | |||
// HTML 支持的希腊字母 | |||
function strGreeceDiscode(str) { | |||
str = str.replace(/Α|Α|Α/g, 'Α'); | |||
str = str.replace(/Β|Β|Β/g, 'Β'); | |||
str = str.replace(/Γ|Γ|Γ/g, 'Γ'); | |||
str = str.replace(/Δ|Δ|Δ/g, 'Δ'); | |||
str = str.replace(/Ε|Ε|Ε/g, 'Ε'); | |||
str = str.replace(/Ζ|Ζ|Ζ/g, 'Ζ'); | |||
str = str.replace(/Η|Η|Η/g, 'Η'); | |||
str = str.replace(/Θ|Θ|Θ/g, 'Θ'); | |||
str = str.replace(/Ι|Ι|Ι/g, 'Ι'); | |||
str = str.replace(/Κ|Κ|Κ/g, 'Κ'); | |||
str = str.replace(/Λ|Λ|Λ/g, 'Λ'); | |||
str = str.replace(/Μ|Μ|Μ/g, 'Μ'); | |||
str = str.replace(/Ν|Ν|Ν/g, 'Ν'); | |||
str = str.replace(/Ξ|Ν|Ν/g, 'Ν'); | |||
str = str.replace(/Ο|Ο|Ο/g, 'Ο'); | |||
str = str.replace(/Π|Π|Π/g, 'Π'); | |||
str = str.replace(/Ρ|Ρ|Ρ/g, 'Ρ'); | |||
str = str.replace(/Σ|Σ|Σ/g, 'Σ'); | |||
str = str.replace(/Τ|Τ|Τ/g, 'Τ'); | |||
str = str.replace(/Υ|Υ|Υ/g, 'Υ'); | |||
str = str.replace(/Φ|Φ|Φ/g, 'Φ'); | |||
str = str.replace(/Χ|Χ|Χ/g, 'Χ'); | |||
str = str.replace(/Ψ|Ψ|Ψ/g, 'Ψ'); | |||
str = str.replace(/Ω|Ω|Ω/g, 'Ω'); | |||
str = str.replace(/α|α|α/g, 'α'); | |||
str = str.replace(/β|β|β/g, 'β'); | |||
str = str.replace(/γ|γ|γ/g, 'γ'); | |||
str = str.replace(/δ|δ|δ/g, 'δ'); | |||
str = str.replace(/ε|ε|ε/g, 'ε'); | |||
str = str.replace(/ζ|ζ|ζ/g, 'ζ'); | |||
str = str.replace(/η|η|η/g, 'η'); | |||
str = str.replace(/θ|θ|θ/g, 'θ'); | |||
str = str.replace(/ι|ι|ι/g, 'ι'); | |||
str = str.replace(/κ|κ|κ/g, 'κ'); | |||
str = str.replace(/λ|λ|λ/g, 'λ'); | |||
str = str.replace(/μ|μ|μ/g, 'μ'); | |||
str = str.replace(/ν|ν|ν/g, 'ν'); | |||
str = str.replace(/ξ|ξ|ξ/g, 'ξ'); | |||
str = str.replace(/ο|ο|ο/g, 'ο'); | |||
str = str.replace(/π|π|π/g, 'π'); | |||
str = str.replace(/ρ|ρ|ρ/g, 'ρ'); | |||
str = str.replace(/ς|ς|ς/g, 'ς'); | |||
str = str.replace(/σ|σ|σ/g, 'σ'); | |||
str = str.replace(/τ|τ|τ/g, 'τ'); | |||
str = str.replace(/υ|υ|υ/g, 'υ'); | |||
str = str.replace(/φ|φ|φ/g, 'φ'); | |||
str = str.replace(/χ|χ|χ/g, 'χ'); | |||
str = str.replace(/ψ|ψ|ψ/g, 'ψ'); | |||
str = str.replace(/ω|ω|ω/g, 'ω'); | |||
str = str.replace(/ϑ|ϑ|ϑ/g, 'ϑ'); | |||
str = str.replace(/ϒ|ϒ|ϒ/g, 'ϒ'); | |||
str = str.replace(/ϖ|ϖ|ϖ/g, 'ϖ'); | |||
str = str.replace(/·|·|·/g, '·'); | |||
return str; | |||
} | |||
function strcharacterDiscode(str) { | |||
// 加入常用解析 | |||
// str = str.replace(/ | | /g, " "); | |||
// str = str.replace(/ | | /g, ' '); | |||
// str = str.replace(/ | /g, '<span class=\'spaceshow\'> </span>'); | |||
// str = str.replace(/ | | /g, ' '); | |||
// str = str.replace(/"|"|"/g, "\""); | |||
// str = str.replace(/'|'|'/g, "'"); | |||
// str = str.replace(/´|´|´/g, "´"); | |||
// str = str.replace(/×|×|×/g, "×"); | |||
// str = str.replace(/÷|÷|÷/g, "÷"); | |||
// str = str.replace(/&|&|&/g, '&'); | |||
// str = str.replace(/<|<|</g, '<'); | |||
// str = str.replace(/>|>|>/g, '>'); | |||
str = str.replace(/ | | /g, "<span class='spaceshow'> </span>"); | |||
str = str.replace(/ | | /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/ | /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/ | | /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/"|"|"/g, "\""); | |||
str = str.replace(/"|'|'/g, "'"); | |||
str = str.replace(/´|´|´/g, "´"); | |||
str = str.replace(/×|×|×/g, "×"); | |||
str = str.replace(/÷|÷|÷/g, "÷"); | |||
str = str.replace(/&|&|&/g, '&'); | |||
str = str.replace(/<|<|</g, '<'); | |||
str = str.replace(/>|>|>/g, '>'); | |||
return str; | |||
} | |||
// HTML 支持的其他实体 | |||
function strOtherDiscode(str) { | |||
str = str.replace(/Œ|Œ|Œ/g, 'Œ'); | |||
str = str.replace(/œ|œ|œ/g, 'œ'); | |||
str = str.replace(/Š|Š|Š/g, 'Š'); | |||
str = str.replace(/š|š|š/g, 'š'); | |||
str = str.replace(/Ÿ|Ÿ|Ÿ/g, 'Ÿ'); | |||
str = str.replace(/ƒ|ƒ|ƒ/g, 'ƒ'); | |||
str = str.replace(/ˆ|ˆ|ˆ/g, 'ˆ'); | |||
str = str.replace(/˜|˜|˜/g, '˜'); | |||
str = str.replace(/ |$#8201;| /g, '<span class=\'spaceshow\'> </span>'); | |||
str = str.replace(/‌|‌|‌/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/‍|$#8205;|‍/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/‎|$#8206;|‎/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/‏|‏|‏/g, '<span class=\'spaceshow\'></span>'); | |||
str = str.replace(/–|–|–/g, '–'); | |||
str = str.replace(/—|—|—/g, '—'); | |||
str = str.replace(/‘|‘|‘/g, '‘'); | |||
str = str.replace(/’|’|’/g, '’'); | |||
str = str.replace(/‚|‚|‚/g, '‚'); | |||
str = str.replace(/“|“|“/g, '“'); | |||
str = str.replace(/”|”|”/g, '”'); | |||
str = str.replace(/„|„|„/g, '„'); | |||
str = str.replace(/†|†|†/g, '†'); | |||
str = str.replace(/‡|‡|‡/g, '‡'); | |||
str = str.replace(/•|•|•/g, '•'); | |||
str = str.replace(/…|…|…/g, '…'); | |||
str = str.replace(/‰|‰|‰/g, '‰'); | |||
str = str.replace(/′|′|′/g, '′'); | |||
str = str.replace(/″|″|″/g, '″'); | |||
str = str.replace(/‹|‹|‹/g, '‹'); | |||
str = str.replace(/›|›|›/g, '›'); | |||
str = str.replace(/‾|‾|‾/g, '‾'); | |||
str = str.replace(/€|€|€/g, '€'); | |||
str = str.replace(/™|™|™/g, '™'); | |||
str = str.replace(/←|←|←/g, '←'); | |||
str = str.replace(/↑|↑|↑/g, '↑'); | |||
str = str.replace(/→|→|→/g, '→'); | |||
str = str.replace(/↓|↓|↓/g, '↓'); | |||
str = str.replace(/↔|↔|↔/g, '↔'); | |||
str = str.replace(/↵|↵|↵/g, '↵'); | |||
str = str.replace(/⌈|⌈|⌈/g, '⌈'); | |||
str = str.replace(/⌉|⌉|⌉/g, '⌉'); | |||
str = str.replace(/⌊|⌊|⌊/g, '⌊'); | |||
str = str.replace(/⌋|⌋|⌋/g, '⌋'); | |||
str = str.replace(/◊|◊|◊/g, '◊'); | |||
str = str.replace(/♠|♠|♠/g, '♠'); | |||
str = str.replace(/♣|♣|♣/g, '♣'); | |||
str = str.replace(/♥|♥|♥/g, '♥'); | |||
str = str.replace(/♦|♦|♦/g, '♦'); | |||
return str; | |||
} | |||
function strDiscode(str) { | |||
str = strNumDiscode(str); | |||
str = strGreeceDiscode(str); | |||
str = strcharacterDiscode(str); | |||
str = strOtherDiscode(str); | |||
return str; | |||
} | |||
function urlToHttpUrl(url, domain) { | |||
if (/^\/\//.test(url)) { | |||
return `https:${url}`; | |||
} else if (/^\//.test(url)) { | |||
return `https://${domain}${url}`; | |||
} | |||
return url; | |||
} | |||
export default { | |||
strDiscode, | |||
urlToHttpUrl, | |||
}; |
@@ -0,0 +1,258 @@ | |||
/** | |||
* author: Di (微信小程序开发工程师) | |||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | |||
* 垂直微信小程序开发交流社区 | |||
* | |||
* github地址: https://github.com/icindy/wxParse | |||
* | |||
* for: 微信小程序富文本解析 | |||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | |||
*/ | |||
/** | |||
* 请在全局下引入该文件,@import '/static/wxParse.css'; | |||
*/ | |||
.wxParse { | |||
user-select:none; | |||
width: 100%; | |||
font-family: Helvetica, "PingFangSC", 'Microsoft Yahei', '微软雅黑', Arial, sans-serif; | |||
color: #333; | |||
line-height: 1.5; | |||
font-size: 1em; | |||
text-align:justify;/* //左右两端对齐 */ | |||
} | |||
.wxParse view ,.wxParse uni-view{ | |||
word-break: break-word; | |||
} | |||
.wxParse .p { | |||
padding-bottom: 0.5em; | |||
clear: both; | |||
/* letter-spacing: 0;//字间距 */ | |||
} | |||
.wxParse .inline { | |||
display: inline; | |||
margin: 0; | |||
padding: 0; | |||
} | |||
.wxParse .div { | |||
margin: 0; | |||
padding: 0; | |||
display: block; | |||
} | |||
.wxParse .h1{ | |||
font-size: 2em; | |||
line-height: 1.2em; | |||
margin: 0.67em 0; | |||
} | |||
.wxParse .h2{ | |||
font-size: 1.5em; | |||
margin: 0.83em 0; | |||
} | |||
.wxParse .h3{ | |||
font-size: 1.17em; | |||
margin: 1em 0; | |||
} | |||
.wxParse .h4{ | |||
margin: 1.33em 0; | |||
} | |||
.wxParse .h5{ | |||
font-size: 0.83em; | |||
margin: 1.67em 0; | |||
} | |||
.wxParse .h6{ | |||
font-size: 0.83em; | |||
margin: 1.67em 0; | |||
} | |||
.wxParse .h1, | |||
.wxParse .h2, | |||
.wxParse .h3, | |||
.wxParse .h4, | |||
.wxParse .h5, | |||
.wxParse .h6, | |||
.wxParse .b, | |||
.wxParse .strong{ | |||
font-weight: bolder; | |||
} | |||
.wxParse .i, | |||
.wxParse .cite, | |||
.wxParse .em, | |||
.wxParse .var, | |||
.wxParse .address { | |||
font-style: italic; | |||
} | |||
.wxParse .spaceshow{ | |||
white-space: pre; | |||
} | |||
.wxParse .pre, | |||
.wxParse .tt, | |||
.wxParse .code, | |||
.wxParse .kbd, | |||
.wxParse .samp { | |||
font-family: monospace; | |||
} | |||
.wxParse .pre { | |||
overflow: auto; | |||
background: #f5f5f5; | |||
padding: 16upx; | |||
white-space: pre; | |||
margin: 1em 0upx; | |||
font-size: 24upx; | |||
} | |||
.wxParse .code { | |||
overflow: auto; | |||
padding: 16upx; | |||
white-space: pre; | |||
margin: 1em 0upx; | |||
background: #f5f5f5; | |||
font-size: 24upx; | |||
} | |||
.wxParse .big { | |||
font-size: 1.17em; | |||
} | |||
.wxParse .small, | |||
.wxParse .sub, | |||
.wxParse .sup { | |||
font-size: 0.83em; | |||
} | |||
.wxParse .sub { | |||
vertical-align: sub; | |||
} | |||
.wxParse .sup { | |||
vertical-align: super; | |||
} | |||
.wxParse .s, | |||
.wxParse .strike, | |||
.wxParse .del { | |||
text-decoration: line-through; | |||
} | |||
.wxParse .strong, | |||
.wxParse .text, | |||
.wxParse .span, | |||
.wxParse .s { | |||
display: inline; | |||
} | |||
.wxParse .a { | |||
color: deepskyblue; | |||
} | |||
.wxParse .video { | |||
text-align: center; | |||
margin: 22upx 0; | |||
} | |||
.wxParse .video-video { | |||
width: 100%; | |||
} | |||
.wxParse .uni-image{ | |||
max-width: 100%; | |||
} | |||
.wxParse .img { | |||
display: block; | |||
max-width: 100%; | |||
margin-bottom: 0em;/* //与p标签底部padding同时修改 */ | |||
overflow: hidden; | |||
} | |||
.wxParse .blockquote { | |||
margin: 10upx 0; | |||
padding: 22upx 0 22upx 22upx; | |||
font-family: Courier, Calibri, "宋体"; | |||
background: #f5f5f5; | |||
border-left: 6upx solid #dbdbdb; | |||
} | |||
.wxParse .blockquote .p { | |||
margin: 0; | |||
} | |||
.wxParse .ul, .wxParse .ol { | |||
display: block; | |||
margin: 1em 0; | |||
padding-left: 2em; | |||
} | |||
.wxParse .ol { | |||
list-style-type: disc; | |||
} | |||
.wxParse .ol { | |||
list-style-type: decimal; | |||
} | |||
.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template { | |||
display: list-item; | |||
align-items: baseline; | |||
text-align: match-parent; | |||
} | |||
.wxParse .ol>.li,.wxParse .ul>.li { | |||
display: list-item; | |||
align-items: baseline; | |||
text-align: match-parent; | |||
} | |||
.wxParse .ul .ul, .wxParse .ol .ul { | |||
list-style-type: circle; | |||
} | |||
.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul { | |||
list-style-type: square; | |||
} | |||
.wxParse .u { | |||
text-decoration: underline; | |||
} | |||
.wxParse .hide { | |||
display: none; | |||
} | |||
.wxParse .del { | |||
display: inline; | |||
} | |||
.wxParse .figure { | |||
overflow: hidden; | |||
} | |||
.wxParse .tablebox{ | |||
overflow: auto; | |||
background-color: #f5f5f5; | |||
background: #f5f5f5; | |||
font-size: 13px; | |||
padding: 8px; | |||
} | |||
.wxParse .table .table,.wxParse .table{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
/* 内边框 */ | |||
/* width: 100%; */ | |||
overflow: auto; | |||
white-space: pre; | |||
} | |||
.wxParse .tbody{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
/* 内边框 */ | |||
border: 1px solid #dadada; | |||
} | |||
.wxParse .table .thead, .wxParse .table .tfoot, .wxParse .table .th{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
background: #ececec; | |||
font-weight: 40; | |||
} | |||
.wxParse .table .tr { | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
/* border: 2px solid #F0AD4E; */ | |||
overflow:auto; | |||
} | |||
.wxParse .table .th, | |||
.wxParse .table .td{ | |||
border-collapse:collapse; | |||
box-sizing: border-box; | |||
border: 2upx solid #dadada; | |||
overflow:auto; | |||
} | |||
.wxParse .audio, .wxParse .uni-audio-default{ | |||
display: block; | |||
} |
@@ -0,0 +1,228 @@ | |||
<!--** | |||
* forked from:https://github.com/F-loat/mpvue-wxParse | |||
* | |||
* github地址: https://github.com/dcloudio/uParse | |||
* | |||
* for: uni-app框架下 富文本解析 | |||
* | |||
* 优化 by gaoyia@qq.com https://github.com/gaoyia/parse | |||
*/--> | |||
<template> | |||
<!--基础元素--> | |||
<div class="wxParse" :class="className" :style="'user-select:' + userSelect"> | |||
<block v-for="(node, index) of nodes" :key="index" v-if="!loading"> | |||
<wxParseTemplate :node="node" /> | |||
</block> | |||
</div> | |||
</template> | |||
<script> | |||
import HtmlToJson from './libs/html2json'; | |||
import wxParseTemplate from './components/wxParseTemplate0'; | |||
export default { | |||
name: 'wxParse', | |||
props: { | |||
// user-select:none; | |||
userSelect: { | |||
type: String, | |||
default: 'text' //none |text| all | element | |||
}, | |||
imgOptions: { | |||
type: [Object, Boolean], | |||
default: function() { | |||
return { | |||
loop: false, | |||
indicator: 'number', | |||
longPressActions: false | |||
// longPressActions: { | |||
// itemList: ['发送给朋友', '保存图片', '收藏'], | |||
// success: function (res) { | |||
// console.log('选中了第' + (res.tapIndex + 1) + '个按钮'); | |||
// }, | |||
// fail: function (res) { | |||
// console.log(res.errMsg); | |||
// } | |||
// } | |||
// } | |||
} | |||
} | |||
}, | |||
loading: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
className: { | |||
type: String, | |||
default: '' | |||
}, | |||
content: { | |||
type: String, | |||
default: '' | |||
}, | |||
noData: { | |||
type: String, | |||
default: '<div style="color: red;">数据不能为空</div>' | |||
}, | |||
startHandler: { | |||
type: Function, | |||
default () { | |||
return node => { | |||
node.attr.class = null; | |||
node.attr.style = null; | |||
}; | |||
} | |||
}, | |||
endHandler: { | |||
type: Function, | |||
default: null | |||
}, | |||
charsHandler: { | |||
type: Function, | |||
default: null | |||
}, | |||
imageProp: { | |||
type: Object, | |||
default () { | |||
return { | |||
mode: 'aspectFit', | |||
padding: 0, | |||
lazyLoad: false, | |||
domain: '' | |||
}; | |||
} | |||
} | |||
}, | |||
components: { | |||
wxParseTemplate | |||
}, | |||
data() { | |||
return { | |||
nodes: {}, | |||
imageUrls: [], | |||
wxParseWidth: { | |||
value: 0 | |||
} | |||
}; | |||
}, | |||
computed: {}, | |||
mounted() { | |||
this.setHtml() | |||
}, | |||
methods: { | |||
setHtml() { | |||
this.getWidth().then((data) => { | |||
this.wxParseWidth.value = data; | |||
}) | |||
let { | |||
content, | |||
noData, | |||
imageProp, | |||
startHandler, | |||
endHandler, | |||
charsHandler | |||
} = this; | |||
let parseData = content || noData; | |||
let customHandler = { | |||
start: startHandler, | |||
end: endHandler, | |||
chars: charsHandler | |||
}; | |||
let results = HtmlToJson(parseData, customHandler, imageProp, this); | |||
this.imageUrls = results.imageUrls; | |||
// this.nodes = results.nodes; | |||
this.nodes = []; | |||
results.nodes.forEach((item) => { | |||
setTimeout(() => { | |||
this.nodes.push(item) | |||
}, 0); | |||
}) | |||
}, | |||
getWidth() { | |||
return new Promise((res, rej) => { | |||
// #ifndef MP-ALIPAY || MP-BAIDU | |||
uni.createSelectorQuery() | |||
.in(this) | |||
.select('.wxParse') | |||
.fields({ | |||
size: true, | |||
scrollOffset: true | |||
}, | |||
data => { | |||
res(data.width); | |||
} | |||
).exec(); | |||
// #endif | |||
// #ifdef MP-BAIDU | |||
const query = swan.createSelectorQuery(); | |||
query.select('.wxParse').boundingClientRect(); | |||
query.exec(obj => { | |||
const rect = obj[0] | |||
if (rect) { | |||
res(rect.width); | |||
} | |||
}); | |||
// #endif | |||
// #ifdef MP-ALIPAY | |||
my.createSelectorQuery() | |||
.select('.wxParse') | |||
.boundingClientRect().exec((ret) => { | |||
res(ret[0].width); | |||
}); | |||
// #endif | |||
}); | |||
}, | |||
navigate(href, $event, attr) { | |||
console.log(href, attr); | |||
this.$emit('navigate', href, $event); | |||
}, | |||
preview(src, $event) { | |||
if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') { | |||
} else { | |||
uni.previewImage({ | |||
current: src, | |||
urls: this.imageUrls, | |||
loop: this.imgOptions.loop, | |||
indicator: this.imgOptions.indicator, | |||
longPressActions: this.imgOptions.longPressActions | |||
}); | |||
} | |||
this.$emit('preview', src, $event); | |||
}, | |||
removeImageUrl(src) { | |||
const { | |||
imageUrls | |||
} = this; | |||
imageUrls.splice(imageUrls.indexOf(src), 1); | |||
} | |||
}, | |||
// 父组件中提供 | |||
provide() { | |||
return { | |||
parseWidth: this.wxParseWidth, | |||
parseSelect: this.userSelect | |||
// 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。 | |||
}; | |||
}, | |||
watch: { | |||
content(){ | |||
this.setHtml() | |||
} | |||
// content: { | |||
// handler: function(newVal, oldVal) { | |||
// if (newVal !== oldVal) { | |||
// | |||
// } | |||
// }, | |||
// deep: true | |||
// } | |||
} | |||
}; | |||
</script> |
@@ -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> |
@@ -0,0 +1,462 @@ | |||
<template> | |||
<view> | |||
<!-- 播放块 --> | |||
<view class="bottomhead"> | |||
<view class="audio-play" @tap="changePlayState"> | |||
<image class="image" mode="widthFix" | |||
:src="audioPlay ? 'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/pause.png' : 'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/play.png'"> | |||
</image> | |||
</view> | |||
<view class="audio-slider"> | |||
<view class="audio-time"> | |||
<text>{{currentTimeStr}}</text> | |||
</view> | |||
<slider class="slider" min="0" :max="sliderMax" @change="sliderChangeComplate" block-size="14" | |||
:value="sliderValue" activeColor="blue"></slider> | |||
<view class="audio-time"> | |||
<text>{{timeStr}}</text> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("@/utils/util.js"); | |||
var config = require("@/config"); | |||
export default { | |||
name: "long_audio", | |||
data() { | |||
return { | |||
audioPlay: false, //当前的播放状态控制 | |||
sliderValue: 0, //进度条最小值 | |||
sliderMax: 0, //进度条最大值 | |||
innerAudioContext:null, //播放实例 | |||
currentTimeStr: "00:00", //当前进度的时间 | |||
timeStr: "00:00", //总的时间 | |||
recordPath: "", | |||
luyinList: [], //录音文件 | |||
newluyinList: [], | |||
dialogList: [], //录音识别列表 | |||
csdFileindex: 0, | |||
date: "", //年月日 | |||
scrollId: "", | |||
playNow: 0, | |||
alltimeStr: "00:00:00", | |||
}; | |||
}, | |||
props:{ | |||
customerId:'', | |||
infos:null, | |||
roleindex:0 | |||
}, | |||
mounted() { | |||
this.roleindex = 0; | |||
this.innerAudioContext = uni.createInnerAudioContext(); | |||
this.innerAudioContext.autoplay = false; | |||
this.innerAudioContext.title = '音频'; | |||
this.onPlay() | |||
this.onPause() | |||
this.onCanplay() | |||
this.onEnded() | |||
this.onSeeking() | |||
this.onSeeked() | |||
this.TimeUpdate() | |||
this.init(this.infos) | |||
}, | |||
destroyed() { | |||
//暂停 | |||
this.innerAudioContext.pause() | |||
// 销毁 | |||
// this.innerAudioContext.destroy(); | |||
}, | |||
methods: { | |||
onPlay() { | |||
this.innerAudioContext.onPlay(() => { | |||
// 播放监听 | |||
console.log('播放!'); | |||
this.audioPlay = true; | |||
wx.enableAlertBeforeUnload({ | |||
message: "是否确认退出详情页面?", | |||
success: function(res) { | |||
console.log("方法注册成功:", res); | |||
}, | |||
fail: function(errMsg) { | |||
console.log("方法注册失败:", errMsg); | |||
}, | |||
}); | |||
}); | |||
}, | |||
onPause() { | |||
this.innerAudioContext.onPause(() => { | |||
wx.disableAlertBeforeUnload({ | |||
success: function(res) { | |||
console.log(res) | |||
}, | |||
fail: function(e) { | |||
console.log(e) | |||
} | |||
}); | |||
// 暂停监听 | |||
console.log('暂停播放!'); | |||
this.audioPlay = false | |||
}); | |||
}, | |||
onCanplay() { | |||
this.innerAudioContext.onCanplay((callback) => { | |||
console.log("缓冲回调", this.innerAudioContext.duration); | |||
}) | |||
}, | |||
onEnded() { | |||
this.innerAudioContext.onEnded(() => { | |||
// 结束播放监听 | |||
console.log('播放结束!'); | |||
this.audioPlay = false; | |||
}); | |||
}, | |||
onSeeking() { | |||
this.innerAudioContext.onSeeking((res) => { | |||
console.log("进行跳转", res); | |||
}) | |||
}, | |||
onSeeked() { | |||
this.innerAudioContext.onSeeked((res) => { | |||
console.log("结束跳转", res); | |||
this.$forceUpdate() | |||
}); | |||
}, | |||
TimeUpdate() { | |||
this.innerAudioContext.onTimeUpdate(() => { | |||
// var pages = getCurrentPages(); | |||
// if(pages[pages.length-1].route!="pages/mine/details2"){ | |||
// this.innerAudioContext.destroy(); | |||
// } | |||
const { | |||
currentTime, | |||
duration | |||
} = this.innerAudioContext; | |||
console.log(currentTime, 'TimeUpdate, currentTime') | |||
this.playNow = parseInt(currentTime * 1000) | |||
uni.$emit("playNows", this.playNow) | |||
console.log(this.playNow) | |||
if (this.dialogList.length == 0) { | |||
return | |||
} else { | |||
const message = this.dialogList[0].message; | |||
for (let i = 0; i < message.length; i++) { | |||
if (Number(message[i].bg) < this.playNow && Number(message[i].ed) > this.playNow) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
uni.$emit("scrollIds", this.scrollId) | |||
break; | |||
} | |||
} | |||
} | |||
const currTimeStr = this.formatTime(currentTime); | |||
this.sliderValue = parseInt(currentTime); | |||
// 变动的时间 | |||
this.currentTimeStr = currTimeStr; | |||
//进度条最大值 | |||
this.sliderMax = this.luyinList[this.csdFileindex].recordDuration; | |||
this.$forceUpdate() | |||
}); | |||
}, | |||
//分角色标记刷新 | |||
fenjiaoseunfo() { | |||
var bgcd = this.sliderValue * 1000; | |||
this.newluyinList = []; | |||
this.dialogList = []; | |||
uni.request({ | |||
url: config.service.getCorpusAnal + '?corpusId=' + this.luyinList[this.csdFileindex].id + | |||
"&bg=" + bgcd + "&speaker=" + this.roleindex + '&num=50', //仅为示例,并非真实接口地址。 | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
this.tablist = []; | |||
let jsonInfo = JSON.parse(data.data.data.audioContent); | |||
for (var i = 0; i <= data.data.data.speakerNum; i++) { | |||
if (i === 0) { | |||
this.tablist.push({ | |||
name: '全部' | |||
}) | |||
} else { | |||
this.tablist.push({ | |||
name: String.fromCharCode(i + 64) | |||
}) | |||
} | |||
} | |||
if (data.data.data.speaker == null) { | |||
this.roleindexbiaoji = 0; | |||
this.dshfkjsdkksodofydwfkhwdfkjh = 0; | |||
} else { | |||
this.tablist[data.data.data.speaker].name = this.tablist[data.data.data.speaker] | |||
.name + "顾问"; | |||
this.roleindexbiaoji = data.data.data.speaker - 1; | |||
this.dshfkjsdkksodofydwfkhwdfkjh = data.data.data.speaker - 1; | |||
} | |||
if (this.roleindex > this.tablist.length - 1) { | |||
this.roleindex = this.tablist.length - 1 | |||
this.fenjiaoseunfo() | |||
} | |||
this.speaker = data.data.data.speaker; | |||
//上拉标记点 | |||
this.textindex = data.data.data.index; | |||
//下拉标记点 | |||
this.toptextindex = data.data.data.index; | |||
jsonInfo.forEach(item => { | |||
item.message = JSON.parse(item.onebest) | |||
item.backindex = this.csdFileindex | |||
}) | |||
console.log(jsonInfo) | |||
this.newluyinList = jsonInfo; | |||
if (this.textindex == null) { | |||
return | |||
} else { | |||
this.dialogList.push(jsonInfo[this.textindex]); | |||
} | |||
} | |||
}) | |||
}, | |||
// 获取转义后的对话结果 | |||
getCorpusAnalysis(info) { | |||
this.dialogList = []; | |||
this.newluyinList = [] | |||
uni.request({ | |||
url: config.service.getCorpusAnal + '?corpusId=' + this.luyinList[this.csdFileindex].id + | |||
"&bg=" + info.bg + "&speaker=" + this.roleindex + '&num=50', //仅为示例,并非真实接口地址。 | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
this.tablist = []; | |||
this.roleindexbiaoji = 0; | |||
let jsonInfo = JSON.parse(data.data.data.audioContent); | |||
for (var i = 0; i <= data.data.data.speakerNum; i++) { | |||
if (i === 0) { | |||
this.tablist.push({ | |||
name: '全部' | |||
}) | |||
} else { | |||
this.tablist.push({ | |||
name: String.fromCharCode(i + 64) | |||
}) | |||
} | |||
} | |||
if (data.data.data.speaker == null) { | |||
this.dshfkjsdkksodofydwfkhwdfkjh = 0; | |||
} else { | |||
this.tablist[data.data.data.speaker].name = this.tablist[data.data.data.speaker] | |||
.name + "顾问"; | |||
this.roleindexbiaoji = data.data.data.speaker - 1; | |||
this.dshfkjsdkksodofydwfkhwdfkjh = data.data.data.speaker - 1; | |||
} | |||
this.speaker = data.data.data.speaker; | |||
//上拉标记点 | |||
this.textindex = data.data.data.index; | |||
//下拉标记点 | |||
this.toptextindex = data.data.data.index; | |||
jsonInfo.forEach(item => { | |||
item.message = JSON.parse(item.onebest) | |||
item.backindex = this.csdFileindex; | |||
if (info.onebest) { | |||
item.message.forEach(che => { | |||
if (che.onebest == info.onebest) { | |||
che.onebest = | |||
`<font style='color: red'>${che.onebest}</font>`; | |||
} | |||
}) | |||
} | |||
}) | |||
this.newluyinList = jsonInfo; | |||
this.dialogList.push(jsonInfo[this.textindex]); | |||
var itc = parseInt(info.bg / 1000) | |||
this.adasdasdasd(itc) | |||
} | |||
}) | |||
}, | |||
init(info) { | |||
this.sliderMax = 0; //进度条最大值 | |||
this.timeStr = "00:00"; //总的时间 | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: this.customerId | |||
} | |||
} | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
if (res && res.length) { | |||
let alltime = 1 + res[0].recordDuration; | |||
this.calibration = res[0].calibration; | |||
if (this.calibration == 0) { | |||
this.kehuyixiangcenterindex = 0; | |||
} else { | |||
this.kehuyixiangcenterindex = 1; | |||
} | |||
this.alltimeStr = this.getTime(alltime) | |||
if (info.bg != 0) { | |||
this.luyinList = res; | |||
this.recordPath = res[0].recordPath | |||
this.sliderMax = this.getTime(res[0].recordDuration) | |||
this.timeStr = this.getTime(res[0].recordDuration) | |||
this.date = res[0].receptionTime; | |||
this.getCorpusAnalysis(info); | |||
this.creatAudio() | |||
} else { | |||
this.luyinList = res; | |||
this.recordPath = res[0].recordPath | |||
this.sliderMax = this.getTime(res[0].recordDuration) | |||
this.timeStr = this.getTime(res[0].recordDuration) | |||
this.date = res[0].receptionTime; | |||
this.getCorpusAnalysis(info); | |||
this.creatAudio() | |||
} | |||
} | |||
}) | |||
}, | |||
//搜索跳转 | |||
adasdasdasd(e) { | |||
const currTimeStr = this.formatTime(e) | |||
this.currentTimeStr = currTimeStr | |||
this.innerAudioContext.seek(e); | |||
if (uni.getStorageSync('entrance') == 1) { | |||
return | |||
} else { | |||
this.innerAudioContext.play(); | |||
} | |||
}, | |||
getTime(time) { | |||
return util.formatSecond(time) | |||
}, | |||
// 录音暂停播放 | |||
changePlayState() { | |||
if (this.audioPlay == false) { | |||
this.innerAudioContext.play(); | |||
} else { | |||
this.innerAudioContext.pause() | |||
} | |||
}, | |||
//音频前进回退 | |||
sliderChangeComplate(e) { | |||
let platetime = e.detail.value * 1000; | |||
this.dialogList = [] | |||
uni.request({ | |||
url: config.service.fastForward + '?corpusId=' + this.luyinList[this.csdFileindex].id + | |||
"&bg=" + platetime, //仅为示例,并非真实接口地址。 | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
this.textindex = data.data.data.index; | |||
this.toptextindex = data.data.data.index; | |||
if (data.data.data.index > this.newluyinList.length) { | |||
this.dialogList.push(this.newluyinList[0]) | |||
} else { | |||
this.dialogList.push(this.newluyinList[data.data.data.index]) | |||
} | |||
console.log(e.detail, '1233333333333333333333333333333333333333333333333333333333333') | |||
const currTimeStr = this.formatTime(e.detail.value) | |||
this.currentTimeStr = currTimeStr | |||
this.innerAudioContext.seek(e.detail.value); | |||
this.innerAudioContext.play(); | |||
} | |||
}) | |||
}, | |||
//录音实例 | |||
creatAudio() { | |||
this.innerAudioContext = uni.createInnerAudioContext(); | |||
if (uni.getStorageSync('entrance') == 1) { | |||
this.innerAudioContext.autoplay = false; | |||
} else { | |||
this.innerAudioContext.autoplay = true; | |||
} | |||
this.innerAudioContext.src = this.recordPath; | |||
this.innerAudioContext.title = '音频'; | |||
this.onPlay() | |||
this.onPause() | |||
this.onCanplay() | |||
this.onEnded() | |||
this.onSeeking() | |||
this.onSeeked() | |||
this.TimeUpdate() | |||
}, | |||
formatTime(num) { | |||
//格式化时间格式 | |||
num = num.toFixed(0); | |||
let second = num % 60; | |||
if (second < 10) second = '0' + second; | |||
let min = Math.floor(num / 60); | |||
if (min < 10) min = '0' + min; | |||
return min + ":" + second; | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss"> | |||
.bottomhead { | |||
width: 100%; | |||
height: 81rpx; | |||
border-bottom: 1px solid #E0E0E0; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
.audio-slider { | |||
width: 87%; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
padding-right: 30rpx; | |||
} | |||
.audio-slider .slider { | |||
width: 100%; | |||
padding: 0px 15rpx; | |||
box-sizing: border-box; | |||
} | |||
.audio-time { | |||
width: 110rpx; | |||
text-align: right; | |||
font-size: 26rpx; | |||
line-height: 28rpx; | |||
color: #70798D; | |||
display: flex; | |||
justify-content: space-between; | |||
} | |||
.audio-play { | |||
width: 48rpx; | |||
height: 48rpx; | |||
flex-shrink: 0; | |||
} | |||
.audio-play .image { | |||
width: 100%; | |||
height: 100%; | |||
margin-left: 30rpx; | |||
} | |||
} | |||
</style> |
@@ -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 | |||
}) | |||
} | |||
} | |||
} |
@@ -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> |
@@ -0,0 +1,10 @@ | |||
export declare function formatSeconds(seconds: number | string): string; | |||
export declare function throttle(fn: Function, wait: number): Function; | |||
export declare class EventBus { | |||
private _events; | |||
constructor(); | |||
protected on(event: any, action: any, fn: () => {}): void; | |||
private has; | |||
protected emit(event: any, data?: any): void; | |||
protected off(event: any, action: any): void; | |||
} |
@@ -0,0 +1,73 @@ | |||
"use strict"; | |||
Object.defineProperty(exports, "__esModule", { | |||
value: true | |||
}); | |||
exports.EventBus = exports.throttle = exports.formatSeconds = void 0; | |||
function formatSeconds(seconds) { | |||
var result = typeof seconds === "string" ? parseFloat(seconds) : seconds; | |||
if (isNaN(result)) return ""; | |||
let h = Math.floor(result / 3600) < 10 ? "0" + Math.floor(result / 3600) : Math.floor(result / 3600); | |||
let m = Math.floor((result / 60) % 60) < 10 ? "0" + Math.floor((result / 60) % 60) : Math.floor((result / 60) % 60); | |||
let s = Math.floor(result % 60) < 10 ? "0" + Math.floor(result % 60) : Math.floor(result % 60); | |||
return `${h}:${m}:${s}`; | |||
//time为毫秒数 | |||
} | |||
exports.formatSeconds = formatSeconds; | |||
function throttle(fn, wait) { | |||
let previous = 0; | |||
return function(...arg) { | |||
let context = this; | |||
let now = Date.now(); | |||
//每隔一段时间执行一次; | |||
if (now - previous > wait) { | |||
fn.apply(context, arg); | |||
previous = now; | |||
} | |||
}; | |||
} | |||
exports.throttle = throttle; | |||
class EventBus { | |||
constructor() { | |||
this._events = new Map(); | |||
} | |||
on(event, action, fn) { | |||
let arr = this._events.get(event); | |||
let hasAction = arr ? | |||
arr.findIndex((i) => i.action == action) : | |||
-1; | |||
if (hasAction > -1) { | |||
return; | |||
} | |||
this._events.set(event, [ | |||
...(this._events.get(event) || []), | |||
{ | |||
action, | |||
fn, | |||
}, | |||
]); | |||
} | |||
has(event) { | |||
return this._events.has(event); | |||
} | |||
emit(event, data) { | |||
if (!this.has(event)) { | |||
return; | |||
} | |||
let arr = this._events.get(event); | |||
arr.forEach((i) => { | |||
i.fn(data); | |||
}); | |||
} | |||
off(event, action) { | |||
if (!this.has(event)) { | |||
return; | |||
} | |||
let arr = this._events.get(event); | |||
let newdata = arr.filter((i) => i.action !== action); | |||
this._events.set(event, [...newdata]); | |||
} | |||
} | |||
exports.EventBus = EventBus; |
@@ -0,0 +1,213 @@ | |||
interface audio { | |||
src: string; | |||
title: string; | |||
singer: string; | |||
coverImgUrl: string; | |||
} | |||
interface audioInfo extends audio { | |||
current: string; | |||
duration: string; | |||
duration_value: number; | |||
current_value: number; | |||
} | |||
declare enum zaudioCbName { | |||
onWaiting = "waiting", | |||
onError = "error", | |||
onTimeUpdate = "playing", | |||
onCanplay = "canPlay", | |||
onPause = "pause", | |||
onEnded = "ended", | |||
setAudio = "setAudio", | |||
updateAudio = "updateAudio", | |||
seek = "seek", | |||
onStop = "stop", | |||
syncStateOn = "syncStateOn" | |||
} | |||
import { EventBus } from "./util"; | |||
/** | |||
* ZAudio类 | |||
* @class ZAudio | |||
* @constructor | |||
* @param {String} defaultCover 音频默认封面 | |||
* @param {Boolean} continuePlay 继续播放,错误播放或结束播放后执行 | |||
* @param {Boolean} autoPlay 自动播放,部分浏览器不支持 | |||
* @property {Number} renderIndex 当前渲染索引 | |||
* @property {<audioinfo>} renderinfo 当前渲染数据 | |||
* @property {Array<audio>} audiolist 音频列表数组 | |||
* @property {<audioinfo>} playinfo 当前播放数据 | |||
* @property {Boolean} paused 音频暂停状态 | |||
* @property {Number} playIndex 当前播放索引 | |||
* @property {Boolean} renderIsPlay 渲染与播放是否一致 | |||
* | |||
* @method on(event, action, fn) 回调函数注册业务事件 | |||
* @method off(event, action) 回调函数中卸载业务事件 | |||
* @method setRender(data) 指定音频, 渲染到zaudio组件 | |||
* @method syncRender() 同步并渲染当前的播放状态 | |||
* @method operate(index) 播放或暂停指定索引的音频 | |||
* @method setAudio(list) 覆盖音频列表 | |||
* @method updateAudio(list) 添加音频列表 | |||
* @method stop() 强制暂停当前播放音频 | |||
* @method stepPlay(count) 快进快退 | |||
* @method syncStateOn(action, cb) 注册一个用于同步获取当前播放状态的事件 | |||
* @method syncStateOff(action) 卸载用于同步获取当前播放状态的事件 | |||
* | |||
* | |||
* **/ | |||
export default class ZAudio extends EventBus { | |||
static version: string; | |||
loading: boolean; | |||
renderIndex: number; | |||
audiolist: Array<audio>; | |||
renderinfo: audioInfo; | |||
playinfo: audioInfo; | |||
paused: boolean; | |||
uPause: boolean; | |||
audioCtx: any; | |||
autoPlay: boolean; | |||
defaultCover: string; | |||
continuePlay: boolean; | |||
constructor(options: { | |||
defaultCover: string; | |||
autoPlay: boolean; | |||
continuePlay: boolean; | |||
}); | |||
private init; | |||
checkEventParams(event: zaudioCbName, action: string | symbol, fn?: () => {}): boolean; | |||
/** | |||
* @description 回调中卸载业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @returns undefined | |||
* **/ | |||
off(event: zaudioCbName, action: string | symbol): void; | |||
/** | |||
* @description 回调中注册业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @param {function(object|string|number|undefined):undefined} fn 业务函数, 参数或为音频状态 | |||
* @returns undefined | |||
* **/ | |||
on(event: zaudioCbName, action: string | symbol, fn: () => {}): void; | |||
/** | |||
* @description 订阅触发音频回调 | |||
* @param {<zaudioCbName>} event 回调名称枚举值,具体看zaudioCbName | |||
* @param {object|string|number|undefined} data 订阅触发回调时,传的音频属性 | |||
* @returns undefined | |||
* **/ | |||
emit(event: zaudioCbName, data?: any): void; | |||
private commit; | |||
private onWaitingHandler; | |||
private onCanplayHandler; | |||
private onPlayHandler; | |||
private onPauseHandler; | |||
private onStopHandler; | |||
private onEndedHandler; | |||
private throttlePlaying; | |||
private onTimeUpdateHandler; | |||
private onErrorHandler; | |||
/** | |||
* @description 实时渲染当前状态 | |||
* @returns undefined | |||
* **/ | |||
syncRender(): void; | |||
/** | |||
* @description 注册一个实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @param {Funtion} fn 实时获取ZAudio属性回调 | |||
* @returns undefined | |||
* **/ | |||
syncStateOn(action: string, fn: () => {}): void; | |||
/** | |||
* @description 卸载实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @returns undefined | |||
* **/ | |||
syncStateOff(action: string): void; | |||
/** | |||
* @description 订阅实时获取ZAudio属性的方法 | |||
* @returns undefined | |||
* **/ | |||
private syncStateEmit; | |||
/** | |||
* @description 跳转播放 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
seek(value: number): void; | |||
/** | |||
* @description 快进 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
stepPlay(value: number): void; | |||
/** | |||
* @description 获取下一首歌曲索引(用于渲染和播放) | |||
* @param {Number} count 切换数量 | |||
* @returns number | |||
* **/ | |||
private getNextKey; | |||
/** | |||
* @description 切歌 | |||
* @param {Number} count 数量 | |||
* @returns undefined | |||
* **/ | |||
changeplay(count: number): void; | |||
/** | |||
* @description 手动播放或暂停, 并渲染对应的数据 | |||
* @param {Number|String|<audioInfo>|undefined} key 索引或音频对象 | |||
* @returns undefined | |||
* **/ | |||
operate(key?: number | string | audioInfo): void; | |||
/** | |||
* @description 强制暂停播放 | |||
* @returns undefined | |||
* **/ | |||
stop(): void; | |||
private operation; | |||
/** | |||
* @description 覆盖音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
setAudio(data: Array<audio>): void; | |||
/** | |||
* @description 添加音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
updateAudio(data: Array<audio>): void; | |||
/** | |||
* @description 设置当前播放信息 | |||
* @param {<audioInfo>} data 音频对象 | |||
* @returns undefined | |||
* **/ | |||
setPlayinfo<T extends keyof audioInfo>(data: audioInfo): void; | |||
/** | |||
* @description 设置暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setPause(data: boolean): void; | |||
/** | |||
* @description 设置loading | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setLoading(data: boolean): void; | |||
/** | |||
* @description 设置通话时暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setUnnormalPause(data: boolean): void; | |||
/** | |||
* @description 设置渲染 | |||
* @param {number | string | audioInfo} data 索引或渲染信息 | |||
* @returns undefined | |||
* **/ | |||
setRender(data: number | string | audioInfo): void; | |||
get playIndex(): number; | |||
get renderIsPlay(): boolean; | |||
private appCheckReplay; | |||
} | |||
export {}; |
@@ -0,0 +1,658 @@ | |||
"use strict"; | |||
var __awaiter = (this && this.__awaiter) || function(thisArg, _arguments, P, generator) { | |||
function adopt(value) { | |||
return value instanceof P ? value : new P(function(resolve) { | |||
resolve(value); | |||
}); | |||
} | |||
return new(P || (P = Promise))(function(resolve, reject) { | |||
function fulfilled(value) { | |||
try { | |||
step(generator.next(value)); | |||
} catch (e) { | |||
reject(e); | |||
} | |||
} | |||
function rejected(value) { | |||
try { | |||
step(generator["throw"](value)); | |||
} catch (e) { | |||
reject(e); | |||
} | |||
} | |||
function step(result) { | |||
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); | |||
} | |||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |||
}); | |||
}; | |||
Object.defineProperty(exports, "__esModule", { | |||
value: true | |||
}); | |||
var zaudioCbName; | |||
(function(zaudioCbName) { | |||
zaudioCbName["onWaiting"] = "waiting"; | |||
zaudioCbName["onError"] = "error"; | |||
zaudioCbName["onTimeUpdate"] = "playing"; | |||
zaudioCbName["onCanplay"] = "canPlay"; | |||
zaudioCbName["onPause"] = "pause"; | |||
zaudioCbName["onEnded"] = "ended"; | |||
zaudioCbName["setAudio"] = "setAudio"; | |||
zaudioCbName["updateAudio"] = "updateAudio"; | |||
zaudioCbName["seek"] = "seek"; | |||
zaudioCbName["onStop"] = "stop"; | |||
zaudioCbName["syncStateOn"] = "syncStateOn"; | |||
})(zaudioCbName || (zaudioCbName = {})); | |||
let zaudioCbNameArr = []; | |||
for (const key in zaudioCbName) { | |||
if (Object.prototype.hasOwnProperty.call(zaudioCbName, key)) { | |||
const item = zaudioCbName[key]; | |||
zaudioCbNameArr.push(item); | |||
} | |||
} | |||
const util_1 = require("./util"); | |||
/** | |||
* ZAudio类 | |||
* @class ZAudio | |||
* @constructor | |||
* @param {String} defaultCover 音频默认封面 | |||
* @param {Boolean} continuePlay 继续播放,错误播放或结束播放后执行 | |||
* @param {Boolean} autoPlay 自动播放,部分浏览器不支持 | |||
* @property {Number} renderIndex 当前渲染索引 | |||
* @property {<audioinfo>} renderinfo 当前渲染数据 | |||
* @property {Array<audio>} audiolist 音频列表数组 | |||
* @property {<audioinfo>} playinfo 当前播放数据 | |||
* @property {Boolean} paused 音频暂停状态 | |||
* @property {Number} playIndex 当前播放索引 | |||
* @property {Boolean} renderIsPlay 渲染与播放是否一致 | |||
* | |||
* @method on(event, action, fn) 回调函数注册业务事件 | |||
* @method off(event, action) 回调函数中卸载业务事件 | |||
* @method setRender(data) 指定音频, 渲染到zaudio组件 | |||
* @method syncRender() 同步并渲染当前的播放状态 | |||
* @method operate(index) 播放或暂停指定索引的音频 | |||
* @method setAudio(list) 覆盖音频列表 | |||
* @method updateAudio(list) 添加音频列表 | |||
* @method stop() 强制暂停当前播放音频 | |||
* @method stepPlay(count) 快进快退 | |||
* @method syncStateOn(action, cb) 注册一个用于同步获取当前播放状态的事件 | |||
* @method syncStateOff(action) 卸载用于同步获取当前播放状态的事件 | |||
* | |||
* | |||
* **/ | |||
class ZAudio extends util_1.EventBus { | |||
constructor(options) { | |||
super(); | |||
this.loading = false; | |||
this.renderIndex = 0; | |||
this.audiolist = []; | |||
this.renderinfo = { | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
current_value: 0, | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}; | |||
this.playinfo = { | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
current_value: 0, | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}; | |||
this.paused = true; | |||
this.uPause = false; | |||
this.autoPlay = false; | |||
this.defaultCover = ""; | |||
this.continuePlay = true; | |||
//fix: 防抖触发音频播放中事件 | |||
this.throttlePlaying = util_1.throttle(() => { | |||
this.emit(zaudioCbName.onTimeUpdate, this.playinfo); | |||
this.syncStateEmit(); | |||
}, 1000); | |||
let { | |||
defaultCover, | |||
autoPlay, | |||
continuePlay | |||
} = options; | |||
this.defaultCover = defaultCover; | |||
this.autoPlay = autoPlay; | |||
this.continuePlay = continuePlay; | |||
this.init(); | |||
} | |||
init() { | |||
// #ifndef H5 | |||
var audioCtx = uni.getBackgroundAudioManager(); | |||
// #endif | |||
// #ifdef H5 | |||
var audioCtx = uni.createInnerAudioContext(); | |||
audioCtx.autoplay = this.autoPlay; | |||
// #endif | |||
this.audioCtx = audioCtx; | |||
this.audioCtx.onWaiting(this.onWaitingHandler.bind(this)); | |||
this.audioCtx.onCanplay(this.onCanplayHandler.bind(this)); | |||
this.audioCtx.onPlay(this.onPlayHandler.bind(this)); | |||
this.audioCtx.onPause(this.onPauseHandler.bind(this)); | |||
this.audioCtx.onStop(this.onStopHandler.bind(this)); | |||
this.audioCtx.onEnded(this.onEndedHandler.bind(this)); | |||
this.audioCtx.onTimeUpdate(this.onTimeUpdateHandler.bind(this)); | |||
this.audioCtx.onError(this.onErrorHandler.bind(this)); | |||
//fix: 修复iOS原生音频切换不起作用 | |||
// #ifdef APP-PLUS | |||
if (uni.getSystemInfoSync().platform == "ios") { | |||
const bgMusic = plus.audio.createPlayer(); | |||
bgMusic.addEventListener("prev", () => { | |||
this.changeplay(-1); | |||
}); | |||
bgMusic.addEventListener("next", () => { | |||
this.changeplay(1); | |||
}); | |||
} | |||
// #endif | |||
// #ifndef H5 | |||
setTimeout(() => { | |||
if (this.autoPlay) { | |||
this.operate(); | |||
} | |||
}, 500); | |||
// #endif | |||
this.appCheckReplay(); | |||
} | |||
//检测on off的参数 | |||
checkEventParams(event, action, fn) { | |||
if (zaudioCbNameArr.indexOf(event) < 0) { | |||
console.error(`参数${event}错误, 必须为${zaudioCbNameArr.join(" | ")}中某一项`); | |||
return false; | |||
} | |||
if (typeof action !== "string" && typeof action !== "symbol") { | |||
console.error(`参数${action}错误, 参数必须为string或symbol类型`); | |||
return false; | |||
} | |||
if (fn && typeof fn !== "function") { | |||
console.error("fn参数错误"); | |||
return false; | |||
} | |||
return true; | |||
} | |||
/** | |||
* @description 回调中卸载业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @returns undefined | |||
* **/ | |||
off(event, action) { | |||
if (!this.checkEventParams(event, action)) | |||
return; | |||
super.off(event, action); | |||
} | |||
/** | |||
* @description 回调中注册业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @param {function(object|string|number|undefined):undefined} fn 业务函数, 参数或为音频状态 | |||
* @returns undefined | |||
* **/ | |||
on(event, action, fn) { | |||
if (!this.checkEventParams(event, action)) | |||
return; | |||
super.on(event, action, fn); | |||
} | |||
/** | |||
* @description 订阅触发音频回调 | |||
* @param {<zaudioCbName>} event 回调名称枚举值,具体看zaudioCbName | |||
* @param {object|string|number|undefined} data 订阅触发回调时,传的音频属性 | |||
* @returns undefined | |||
* **/ | |||
emit(event, data) { | |||
super.emit(event, data); | |||
} | |||
commit(action, data) { | |||
typeof this[action] === "function" && this[action](data); | |||
} | |||
onWaitingHandler() { | |||
this.commit("setLoading", true); | |||
this.emit(zaudioCbName.onWaiting, true); | |||
this.syncStateEmit(); | |||
} | |||
onCanplayHandler() { | |||
this.emit(zaudioCbName.onCanplay, this.playinfo); | |||
this.commit("setLoading", false); | |||
this.syncStateEmit(); | |||
} | |||
onPlayHandler() { | |||
// #ifdef APP-PLUS | |||
this.commit("setPlayinfo", { | |||
duration: util_1.formatSeconds(this.audioCtx.duration), | |||
duration_value: this.audioCtx.duration, | |||
}); | |||
// #endif | |||
this.commit("setPause", false); | |||
this.commit("setUnnormalPause", false); | |||
} | |||
onPauseHandler() { | |||
this.commit("setPause", true); | |||
this.emit(zaudioCbName.onPause); | |||
this.syncStateEmit(); | |||
} | |||
onStopHandler() { | |||
this.commit("setPause", true); | |||
this.emit(zaudioCbName.onStop); | |||
this.syncStateEmit(); | |||
} | |||
onEndedHandler() { | |||
this.commit("setPause", true); | |||
this.audioCtx.startTime = 0; | |||
this.commit("setPlayinfo", { | |||
current: "00:00:00", | |||
current_value: 0, | |||
src: "", | |||
}); | |||
this.emit(zaudioCbName.onEnded); | |||
this.syncStateEmit(); | |||
//续播 | |||
if (this.continuePlay) { | |||
this.changeplay(1); | |||
} else { | |||
let nextkey = this.getNextKey(1); | |||
this.commit("setRender", nextkey); | |||
} | |||
} | |||
onTimeUpdateHandler() { | |||
if (this.renderIsPlay) { | |||
//fix: 解决播放进度大于总进度问题 | |||
let currentTime = this.audioCtx.currentTime | |||
// let currentTime = this.audioCtx.currentTime > this.audioCtx.duration ? | |||
// this.audioCtx.duration : | |||
// this.audioCtx.currentTime; | |||
this.commit("setPlayinfo", { | |||
current: util_1.formatSeconds(currentTime), | |||
current_value: currentTime, | |||
}); | |||
// #ifndef APP-PLUS | |||
//fix: 解决小程序与h5无法获取总进度的问题 | |||
if (this.audioCtx.duration != this.playinfo.duration_value) { | |||
this.commit("setPlayinfo", { | |||
duration: util_1.formatSeconds(this.audioCtx.duration), | |||
duration_value: this.audioCtx.duration, | |||
}); | |||
} | |||
// #endif | |||
} | |||
this.throttlePlaying(); | |||
} | |||
onErrorHandler() { | |||
this.commit("setPause", true); | |||
this.commit("setRender", { | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}); | |||
this.commit("setPlayinfo", { | |||
current: "00:00:00", | |||
current_value: 0, | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
title: "", | |||
src: "", | |||
}); | |||
this.emit(zaudioCbName.onError); | |||
this.syncStateEmit(); | |||
if (this.continuePlay) { | |||
this.changeplay(1); | |||
} | |||
} | |||
/** | |||
* @description 实时渲染当前状态 | |||
* @returns undefined | |||
* **/ | |||
syncRender() { | |||
this.setRender(this.playIndex); | |||
} | |||
/** | |||
* @description 注册一个实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @param {Funtion} fn 实时获取ZAudio属性回调 | |||
* @returns undefined | |||
* **/ | |||
syncStateOn(action, fn) { | |||
typeof fn === "function" && this.on(zaudioCbName.syncStateOn, action, fn); | |||
} | |||
/** | |||
* @description 卸载实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @returns undefined | |||
* **/ | |||
syncStateOff(action) { | |||
this.off(zaudioCbName.syncStateOn, action); | |||
} | |||
/** | |||
* @description 订阅实时获取ZAudio属性的方法 | |||
* @returns undefined | |||
* **/ | |||
syncStateEmit() { | |||
this.emit(zaudioCbName.syncStateOn, { | |||
renderIndex: this.renderIndex, | |||
audiolist: this.audiolist, | |||
renderinfo: this.renderinfo, | |||
playinfo: this.playinfo, | |||
paused: this.paused, | |||
playIndex: this.playIndex, | |||
renderIsPlay: this.renderIsPlay, | |||
loading: this.loading, | |||
}); | |||
} | |||
/** | |||
* @description 跳转播放 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
seek(value) { | |||
let val = value > this.audioCtx.duration ? this.audioCtx.duration : value; | |||
this.audioCtx.seek(val); | |||
this.commit("setPlayinfo", { | |||
current: util_1.formatSeconds(val), | |||
current_value: val, | |||
}); | |||
// setTimeout(() => { | |||
// this.emit(zaudioCbName.seek, this.playinfo.current); | |||
// }, 0); | |||
this.emit(zaudioCbName.seek, this.playinfo.current); | |||
} | |||
/** | |||
* @description 快进 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
stepPlay(value) { | |||
if (this.renderIsPlay) { | |||
let pos = this.playinfo.current_value + value; | |||
this.seek(pos); | |||
} | |||
} | |||
/** | |||
* @description 获取下一首歌曲索引(用于渲染和播放) | |||
* @param {Number} count 切换数量 | |||
* @returns number | |||
* **/ | |||
getNextKey(count) { | |||
let nextkey = this.renderIndex; | |||
nextkey += count; | |||
nextkey = | |||
nextkey < 0 ? | |||
this.audiolist.length - 1 : | |||
nextkey > this.audiolist.length - 1 ? | |||
0 : | |||
nextkey; | |||
return nextkey; | |||
} | |||
/** | |||
* @description 切歌 | |||
* @param {Number} count 数量 | |||
* @returns undefined | |||
* **/ | |||
changeplay(count) { | |||
let nextkey = this.getNextKey(count); | |||
this.commit("setPause", true); | |||
this.operate(nextkey); | |||
} | |||
/** | |||
* @description 手动播放或暂停, 并渲染对应的数据 | |||
* @param {Number|String|<audioInfo>|undefined} key 索引或音频对象 | |||
* @returns undefined | |||
* **/ | |||
operate(key) { | |||
key !== undefined && this.commit("setRender", key); | |||
this.operation(); | |||
} | |||
/** | |||
* @description 强制暂停播放 | |||
* @returns undefined | |||
* **/ | |||
stop() { | |||
this.audioCtx.pause(); | |||
this.commit("setPause", true); | |||
this.commit("setUnnormalPause", true); | |||
this.emit(zaudioCbName.onStop); | |||
} | |||
//播放,暂停事件判断, | |||
//播放数据与渲染数据相同时: 播放->暂停, 暂停->播放 | |||
//播放数据与渲染数据不相同时: 播放渲染音频 | |||
operation() { | |||
return __awaiter(this, void 0, void 0, function*() { | |||
const { | |||
duration, | |||
current, | |||
duration_value, | |||
current_value, | |||
src, | |||
} = this.playinfo; | |||
const { | |||
src: renderSrc, | |||
title: renderTitle, | |||
singer: renderSinger, | |||
coverImgUrl: renderCoverImgUrl, | |||
} = this.renderinfo; | |||
let renderIsPlay = this.renderIsPlay; | |||
let paused = this.paused; | |||
if (!renderIsPlay) { | |||
//渲染与播放地址 不同 | |||
this.audioCtx.src = renderSrc; | |||
this.audioCtx.title = renderTitle; | |||
this.audioCtx.singer = renderSinger; | |||
this.audioCtx.coverImgUrl = renderCoverImgUrl || this.defaultCover; | |||
this.audioCtx.startTime = 0; | |||
this.audioCtx.seek(0); | |||
this.audioCtx.play(); | |||
this.commit("setPause", false); | |||
this.commit("setPlayinfo", { | |||
src: renderSrc, | |||
title: renderTitle, | |||
singer: renderSinger, | |||
coverImgUrl: renderCoverImgUrl, | |||
}); | |||
} else { | |||
if (paused) { | |||
//渲染与播放地址相同 | |||
this.audioCtx.play(); | |||
this.audioCtx.startTime = current_value; | |||
// this.audioCtx.seek(current_value); | |||
this.commit("setPause", false); | |||
this.commit("setPlayinfo", { | |||
src: renderSrc, | |||
title: renderTitle, | |||
singer: renderSinger, | |||
coverImgUrl: renderCoverImgUrl, | |||
}); | |||
} else { | |||
this.audioCtx.pause(); | |||
this.commit("setPause", true); | |||
this.commit("setUnnormalPause", true); | |||
} | |||
} | |||
}); | |||
} | |||
/** | |||
* @description 覆盖音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
setAudio(data) { | |||
this.audiolist = [...data]; | |||
this.emit(zaudioCbName.setAudio, this.audiolist); | |||
this.syncStateEmit(); | |||
} | |||
/** | |||
* @description 添加音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
updateAudio(data) { | |||
this.audiolist.push(...data); | |||
this.emit(zaudioCbName.updateAudio, this.audiolist); | |||
this.syncStateEmit(); | |||
} | |||
/** | |||
* @description 设置当前播放信息 | |||
* @param {<audioInfo>} data 音频对象 | |||
* @returns undefined | |||
* **/ | |||
setPlayinfo(data) { | |||
for (let i in data) { | |||
this.playinfo[i] = data[i]; | |||
} | |||
} | |||
/** | |||
* @description 设置暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setPause(data) { | |||
this.paused = data; | |||
} | |||
/** | |||
* @description 设置loading | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setLoading(data) { | |||
this.loading = data; | |||
} | |||
/** | |||
* @description 设置通话时暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setUnnormalPause(data) { | |||
this.uPause = data; | |||
} | |||
/** | |||
* @description 设置渲染 | |||
* @param {number | string | audioInfo} data 索引或渲染信息 | |||
* @returns undefined | |||
* **/ | |||
setRender(data) { | |||
if (this.audiolist.length == 0) | |||
return; | |||
if (typeof data === "number" || typeof data === "string") { | |||
this.renderIndex = typeof data === "string" ? parseInt(data) : data; | |||
this.renderinfo = { | |||
src: this.audiolist[this.renderIndex].src, | |||
title: this.audiolist[this.renderIndex].title, | |||
singer: this.audiolist[this.renderIndex].singer, | |||
coverImgUrl: this.audiolist[this.renderIndex].coverImgUrl, | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
current_value: 0, | |||
duration_value: 100, | |||
}; | |||
} else { | |||
this.renderinfo = data; | |||
let renderIndex = this.audiolist.findIndex((i) => i.src == data.src); | |||
if (renderIndex >= 0) { | |||
this.renderIndex = renderIndex; | |||
} | |||
} | |||
this.syncStateEmit(); | |||
} | |||
//当前索引 | |||
get playIndex() { | |||
let index = this.audiolist.findIndex((i) => i.src == this.playinfo.src); | |||
return index <= 0 ? 0 : index; | |||
} | |||
//渲染与播放是否一致 | |||
get renderIsPlay() { | |||
return this.renderinfo.src == this.playinfo.src; | |||
} | |||
//app端判断电话来电后, 音频意外中断之后的继续播放 | |||
appCheckReplay() { | |||
let _t = this; | |||
// #ifdef APP-PLUS | |||
try { | |||
if (uni.getSystemInfoSync().platform == "android") { | |||
var main = plus.android.runtimeMainActivity(); | |||
var Context = plus.android.importClass("android.content.Context"); | |||
var telephonyManager = plus.android.importClass("android.telephony.TelephonyManager"); | |||
var telephonyManager = plus.android | |||
.runtimeMainActivity() | |||
.getSystemService(Context.TELEPHONY_SERVICE); | |||
var receiver = plus.android.implements("io.dcloud.android.content.BroadcastReceiver", { | |||
onReceive: function(intent) { | |||
//实现onReceiver回调函数 | |||
plus.android.importClass(intent); | |||
var telephonyManager = plus.android.importClass( | |||
"android.telephony.TelephonyManager"); | |||
var telephonyManager = plus.android | |||
.runtimeMainActivity() | |||
.getSystemService(Context.TELEPHONY_SERVICE); | |||
var phonetype = telephonyManager.getCallState(); | |||
var phoneNumber = intent.getStringExtra(telephonyManager | |||
.EXTRA_INCOMING_NUMBER); | |||
if (phonetype == 0 && !_t.uPause) { | |||
_t.audioCtx.play(); | |||
} | |||
}, | |||
}); | |||
var IntentFilter = plus.android.importClass("android.content.IntentFilter"); | |||
var filter = new IntentFilter(); | |||
filter.addAction(telephonyManager.ACTION_PHONE_STATE_CHANGED); //监听开关 | |||
main.registerReceiver(receiver, filter); //注册监听 | |||
} else if (uni.getSystemInfoSync().platform == "ios") { | |||
var callstatus = false; | |||
var CTCall = plus.ios.importClass("CTCall"); | |||
var CTCallCenter = plus.ios.importClass("CTCallCenter"); | |||
var center = new CTCallCenter(); | |||
center.init(); | |||
center.setCallEventr(function(ctCall) { | |||
callstatus = !callstatus; | |||
if (!callstatus && !_t.uPause) { | |||
_t.audioCtx.play(); | |||
} else { | |||
_t.audioCtx.pause(); | |||
} | |||
}); | |||
} | |||
} catch (err) { | |||
console.warn(err); | |||
} | |||
// #endif | |||
} | |||
// 重置当前的参数 | |||
resetDatas() { | |||
this.loading = false; | |||
this.renderIndex = 0; | |||
this.audiolist = []; | |||
this.renderinfo = { | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
current_value: 0, | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}; | |||
this.playinfo = { | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
current_value: 0, | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}; | |||
} | |||
} | |||
exports.default = ZAudio; | |||
ZAudio.version = "2.2.51"; |
@@ -0,0 +1,2 @@ | |||
import ZAudio from "./dist/zaudio.js"; | |||
export default ZAudio |
@@ -0,0 +1,356 @@ | |||
@mixin textoverflow() { | |||
display: -webkit-box; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 1; | |||
} | |||
@keyframes rowup { | |||
0% { | |||
-webkit-transform: translate(-50%, -50%) rotate(0deg); | |||
transform-origin: center center; | |||
} | |||
100% { | |||
-webkit-transform: translate(-50%, -50%) rotate(360deg); | |||
transform-origin: center center; | |||
} | |||
} | |||
.imt-audio.theme1 { | |||
padding: 0 30upx 30upx; | |||
background: #fff; | |||
.top { | |||
& > view:nth-child(2) { | |||
.title { | |||
font-weight: bold; | |||
font-size: 34rpx; | |||
margin-top: 50rpx; | |||
text-align: center; | |||
} | |||
.singer { | |||
color: #999; | |||
font-size: 26rpx; | |||
margin-top: 10rpx; | |||
text-align: center; | |||
margin-bottom: 18rpx; | |||
} | |||
} | |||
} | |||
.audio-wrapper { | |||
display: flex; | |||
align-items: center; | |||
width: 90%; | |||
margin: 0 auto; | |||
} | |||
.audio-button-box { | |||
display: flex; | |||
align-items: center; | |||
margin: 40rpx auto 0; | |||
justify-content: space-around; | |||
height: 100rpx | |||
} | |||
.audio-number { | |||
font-size: 24upx; | |||
line-height: 1; | |||
color: #333; | |||
} | |||
.audio-slider { | |||
flex: 1; | |||
margin: 0 30rpx 0 35rpx; | |||
} | |||
.audio-control-wrapper { | |||
margin: 20rpx auto; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
position: relative; | |||
} | |||
.cover { | |||
width: 350rpx; | |||
height: 350rpx; | |||
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3); | |||
border-radius: 5px; | |||
} | |||
.playbox{ | |||
width: 100rpx; | |||
height: 100rpx; | |||
display:flex; | |||
align-items: center; | |||
justify-content: center; | |||
} | |||
.play, | |||
.pause { | |||
width: 100rpx; | |||
height: 100rpx; | |||
&.loading{ | |||
width: 80rpx; | |||
height: 80rpx; | |||
animation: rotating 2s linear infinite; | |||
} | |||
} | |||
.prevbtn, | |||
.nextbtn { | |||
width: 40rpx; | |||
height: 40rpx; | |||
} | |||
.prevplay { | |||
width: 40rpx; | |||
height: 40rpx; | |||
transform: rotateZ(180deg); | |||
} | |||
.nextplay { | |||
width: 40rpx; | |||
height: 40rpx; | |||
} | |||
} | |||
.imt-audio.theme2 { | |||
background: #fff; | |||
border: 1px solid #cecece; | |||
width: 100%; | |||
margin: 0 auto; | |||
overflow: hidden; | |||
.top { | |||
background: #fff; | |||
display: flex; | |||
align-items: center; | |||
height: 150rpx; | |||
& > view:nth-child(2) { | |||
flex: 1; | |||
margin: 0 30rpx; | |||
.title { | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
margin-top: 24rpx; | |||
text{ | |||
font-size: 30rpx; | |||
text-align: left; | |||
max-width: 100%; | |||
@include textoverflow; | |||
flex: 1; | |||
} | |||
.audio-number { | |||
font-size: 24upx; | |||
line-height: 1; | |||
color: #333; | |||
} | |||
} | |||
.singer { | |||
color: #999; | |||
font-size: 26rpx; | |||
margin-top: 10rpx; | |||
text-align: left; | |||
margin-bottom: 18rpx; | |||
max-width: 100%; | |||
@include textoverflow; | |||
} | |||
} | |||
} | |||
.cover { | |||
width: 120rpx; | |||
height: 120rpx; | |||
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
border-radius: 50%; | |||
border: 2px solid #fff; | |||
animation-fill-mode: forwards; | |||
-webkit-animation-fill-mode: forwards; | |||
} | |||
.cover.on { | |||
-webkit-animation: 10s rowup linear infinite normal; | |||
animation: 10s rowup linear infinite normal; | |||
animation-fill-mode: forwards; | |||
-webkit-animation-fill-mode: forwards; | |||
} | |||
.audio-control-wrapper{ | |||
width: 150rpx; | |||
height: 150rpx; | |||
display: flex; | |||
align-items:center; | |||
justify-content: center; | |||
background: #efefef; | |||
background-size: contain; | |||
background-position: center; | |||
background-repeat: no-repeat; | |||
} | |||
.play { | |||
width: 80rpx; | |||
height: 80rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
&.loading{ | |||
width: 60rpx; | |||
height: 60rpx; | |||
animation: rotating 2s linear infinite; | |||
} | |||
} | |||
.prevbtn { | |||
width: 48rpx; | |||
height: 48rpx; | |||
margin-right: 40rpx; | |||
} | |||
.nextbtn { | |||
width: 48rpx; | |||
height: 48rpx; | |||
margin-left: 40rpx; | |||
} | |||
} | |||
.imt-audio.theme3 { | |||
background: #ccc; | |||
width: 100%; | |||
overflow: hidden; | |||
display: flex; | |||
padding: 40rpx 20rpx; | |||
box-sizing: border-box; | |||
max-height: 200rpx; | |||
position:relative; | |||
.top { | |||
width: 140rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
position: relative; | |||
} | |||
.audio-wrapper { | |||
display: flex; | |||
flex-direction: column; | |||
flex: 1; | |||
color: #fff; | |||
margin-left: 20rpx; | |||
.titlebox { | |||
display: flex; | |||
line-height: 46rpx; | |||
margin-bottom: 30rpx; | |||
.title { | |||
font-size: 30rpx; | |||
max-width: 50%; | |||
@include textoverflow; | |||
} | |||
.singer { | |||
margin-left: 20rpx; | |||
font-size: 28rpx; | |||
max-width: 50%; | |||
@include textoverflow; | |||
} | |||
} | |||
} | |||
.slidebox { | |||
display: flex; | |||
justify-content: space-between; | |||
width: 96%; | |||
view{ | |||
&:first-child{ | |||
font-size: 28rpx; | |||
} | |||
&:last-child{ | |||
font-size: 28rpx; | |||
text{ | |||
&:last-child{ | |||
margin-left: 40rpx; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
/deep/ .uni-slider-tap-area { | |||
padding: 0; | |||
} | |||
/deep/ .uni-slider-wrapper { | |||
min-height: 0; | |||
} | |||
/deep/ .uni-slider-handle-wrapper { | |||
height: 4px; | |||
} | |||
.audio-slider { | |||
position: absolute; | |||
top: 0; | |||
margin: 0; | |||
width: 100%; | |||
left: 0; | |||
padding: 0; | |||
} | |||
.cover { | |||
width: 120rpx; | |||
height: 120rpx; | |||
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
animation-fill-mode: forwards; | |||
-webkit-animation-fill-mode: forwards; | |||
} | |||
.play { | |||
width: 80rpx; | |||
height: 80rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
&.loading{ | |||
width: 60rpx; | |||
height: 60rpx; | |||
animation: rotating_theme3 2s linear infinite; | |||
} | |||
} | |||
} | |||
@keyframes rotating { | |||
0% { | |||
transform: rotateZ(0deg) | |||
} | |||
100% { | |||
transform: rotateZ(360deg) | |||
} | |||
} | |||
@keyframes rotating_theme3 { | |||
0% { | |||
transform: translate(-50%, -50%) rotateZ(0deg) | |||
} | |||
100% { | |||
transform: translate(-50%, -50%) rotateZ(360deg) | |||
} | |||
} |
@@ -0,0 +1,416 @@ | |||
<template> | |||
<view class="imt-audio" :class="[`${theme}`]" v-if="audiolist.length > 0"> | |||
<template v-if="theme == 'theme4'"> | |||
<view class="imt-audios"> | |||
<view class="top"> | |||
<view class="audio-control-wrapper"> | |||
<image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play" v-else> | |||
</image> | |||
</template> | |||
</view> | |||
</view> | |||
<view class="audio-wrapper"> | |||
<view class="audio-flex"> | |||
<text> | |||
{{renderData('current')}} | |||
</text> | |||
<slider class="audio-slider" :activeColor="themeColor" block-size="16" | |||
:value="renderData('current_value')" :max="renderData('duration_value')" @change="change" | |||
:disabled="!renderIsPlay"></slider> | |||
<text v-if="!duration"> | |||
{{renderData('duration')}} | |||
</text> | |||
<text v-else>{{ duration }}</text> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<template v-if="theme == 'theme3'"> | |||
<slider class="audio-slider" :activeColor="themeColor" block-size="0" :value="renderData('current_value')" | |||
:max="renderData('duration_value')" @change="change" :disabled="!renderIsPlay"></slider> | |||
<view class="top"> | |||
<view class="audio-control-wrapper"> | |||
<image :src="renderData('coverImgUrl')" mode="aspectFill" class="cover" | |||
:class="{ on: !renderData('paused') }"></image> | |||
<image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play" v-else> | |||
</image> | |||
</template> | |||
</view> | |||
</view> | |||
<view class="audio-wrapper"> | |||
<view class="titlebox"> | |||
<view class="title">{{ renderData('title') }}</view> | |||
<view class="singer">{{ renderData('singer') }}</view> | |||
</view> | |||
<view class="slidebox"> | |||
<view>{{ renderData('current') }}/ {{ renderData('duration') }}</view> | |||
<view> | |||
<text @click="changeplay(-1)">上一首</text> | |||
<text @click="changeplay(1)">下一首</text> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<template v-if="theme == 'theme2'"> | |||
<view class="top"> | |||
<view class="audio-control-wrapper" :style="{backgroundImage: `url(${renderData('coverImgUrl')})`}"> | |||
<image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play" v-else> | |||
</image> | |||
</template> | |||
</view> | |||
<view> | |||
<view class="title"> | |||
<text>{{ renderData('title') }}</text> | |||
<view class="audio-number">{{ renderData('current') }}/{{ renderData('duration') }}</view> | |||
</view> | |||
<view class="singer">{{ renderData('singer') }}</view> | |||
</view> | |||
</view> | |||
</template> | |||
<template v-if="theme == 'theme1'"> | |||
<view class="top"> | |||
<view class="audio-control-wrapper"> | |||
<image :src="renderData('coverImgUrl')" mode="aspectFill" class="cover" | |||
:class="{ on: !renderData('paused') }"></image> | |||
</view> | |||
<view> | |||
<view class="title">{{ renderData('title') }}</view> | |||
<view class="singer">{{ renderData('singer') }}</view> | |||
</view> | |||
</view> | |||
<view class="audio-wrapper"> | |||
<view class="audio-number">{{ renderData('current') }}</view> | |||
<slider class="audio-slider" :activeColor="themeColor" block-size="16" | |||
:value="renderData('current_value')" :max="renderData('duration_value')" @change="change" | |||
:disabled="!renderIsPlay"></slider> | |||
<view class="audio-number">{{ renderData('duration') }}</view> | |||
</view> | |||
<view class="audio-button-box"> | |||
<!-- 块退15s --> | |||
<image :src="require('./static/prev.png')" class="prevbtn" @click="stepPlay(-15)" mode="widthFix"> | |||
</image> | |||
<!-- 上一首 --> | |||
<image :src="require('./static/go.png')" class="prevplay" @click="changeplay(-1)" mode="widthFix"> | |||
</image> | |||
<div class="playbox"> | |||
<image :src="require('./static/loading2.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<!-- 播放 --> | |||
<image :src="require('./static/playbtn2.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<!-- 暂停 --> | |||
<image :src="require('./static/pausebtn2.png')" alt="" @click="operate" class="pause" v-else> | |||
</image> | |||
</template> | |||
</div> | |||
<!-- 下一首 --> | |||
<image :src="require('./static/go.png')" class="nextplay" @click="changeplay(1)" mode="widthFix"> | |||
</image> | |||
<!-- 快进15s --> | |||
<image :src="require('./static/next.png')" class="nextbtn" @click="stepPlay(15)" mode="widthFix"> | |||
</image> | |||
</view> | |||
</template> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
props: { | |||
theme: { | |||
type: String, // 主题 'theme1' or 'theme2' | |||
default: 'theme1' | |||
}, | |||
themeColor: { | |||
type: String, | |||
default: '#42b983' | |||
}, | |||
duration: { | |||
type: String, | |||
default: "" | |||
} | |||
}, | |||
data() { | |||
return { | |||
playinfo: this.$zaudio.playinfo, | |||
audiolist: this.$zaudio.audiolist, | |||
paused: this.$zaudio.paused, | |||
renderIsPlay: this.$zaudio.renderIsPlay, | |||
audio: this.$zaudio.renderinfo, | |||
loading: this.$zaudio.loading, | |||
action: Symbol('zaudio') | |||
}; | |||
}, | |||
computed: { | |||
renderData() { | |||
return name => { | |||
if (!this.renderIsPlay) { | |||
if (name == 'paused') { | |||
return true; | |||
} | |||
return this.audio[name]; | |||
} else { | |||
if (name == 'paused') { | |||
return this.paused; | |||
} | |||
return this.playinfo[name]; | |||
} | |||
}; | |||
} | |||
}, | |||
mounted() { | |||
this.$nextTick(() => { | |||
let action = this.action; | |||
this.$zaudio.syncStateOn(action, ({ | |||
audiolist, | |||
paused, | |||
playinfo, | |||
renderIsPlay, | |||
renderinfo, | |||
loading, | |||
}) => { | |||
this.audiolist = audiolist; | |||
this.paused = paused; | |||
this.playinfo = playinfo; | |||
this.renderIsPlay = renderIsPlay; | |||
this.audio = renderinfo; | |||
this.loading = loading; | |||
}); | |||
this.$zaudio.syncRender() | |||
}); | |||
}, | |||
methods: { | |||
// 转换时间 | |||
formatSeconds(seconds) { | |||
var result = typeof seconds === "string" ? parseFloat(seconds) : seconds; | |||
if (isNaN(result)) return ""; | |||
let h = Math.floor(result / 3600) < 10 ? | |||
"0" + Math.floor(result / 3600) : | |||
Math.floor(result / 3600); | |||
let m = Math.floor((result / 60) % 60) < 10 ? | |||
"0" + Math.floor((result / 60) % 60) : | |||
Math.floor((result / 60) % 60) + h * 60; | |||
let s = Math.floor(result % 60) < 10 ? | |||
"0" + Math.floor(result % 60) : | |||
Math.floor(result % 60); | |||
return `${h}:${m}:${s}`; | |||
}, | |||
//播放or暂停 | |||
operate() { | |||
this.$zaudio.operate(); | |||
}, | |||
//进度拖到 | |||
change(event) { | |||
if (this.renderIsPlay) { | |||
console.log('组件内', event) | |||
this.$zaudio.seek(Math.floor(event.detail.value)); | |||
} | |||
}, | |||
//快进 | |||
stepPlay(value) { | |||
this.$zaudio.stepPlay(value); | |||
}, | |||
//切歌 | |||
changeplay(count) { | |||
this.$zaudio.changeplay(count); | |||
}, | |||
}, | |||
beforeDestroy() { | |||
this.$zaudio.playinfo.duration = '00:00:00' | |||
this.$zaudio.playinfo.duration_value = '00:00:00' | |||
//组件卸载时卸载业务逻辑 | |||
let action = this.action; | |||
this.$zaudio.syncStateOff(action) | |||
this.$zaudio.stop() | |||
} | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
@import './index.scss'; | |||
// #ifdef MP-WEIXIN | |||
.theme3 .audio-slider { | |||
margin-top: -8px !important; | |||
} | |||
// #endif | |||
@mixin textoverflow() { | |||
display: -webkit-box; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 1; | |||
} | |||
@keyframes rowup { | |||
0% { | |||
-webkit-transform: translate(-50%, -50%) rotate(0deg); | |||
transform-origin: center center; | |||
} | |||
100% { | |||
-webkit-transform: translate(-50%, -50%) rotate(360deg); | |||
transform-origin: center center; | |||
} | |||
} | |||
.imt-audios { | |||
position: relative; | |||
width: 100%; | |||
height: 81rpx; | |||
display: flex; | |||
box-sizing: border-box; | |||
background: #fff; | |||
.top { | |||
position: relative; | |||
width: 100rpx; | |||
} | |||
.audio-wrapper { | |||
position: relative; | |||
padding: 0 20rpx; | |||
display: flex; | |||
flex: 1; | |||
color: #fff; | |||
.popup { | |||
position: absolute; | |||
right: 32rpx; | |||
top: -122rpx; | |||
z-index: 100; | |||
width: 136rpx; | |||
height: 122rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
flex-direction: column; | |||
background: #fff; | |||
border: 1rpx solid #E0E0E0; | |||
transition: all 0.25s linear; | |||
opacity: 0; | |||
image { | |||
width: 32rpx; | |||
height: 32rpx; | |||
} | |||
text { | |||
margin-top: 10rpx; | |||
color: #333; | |||
font-size: 24rpx; | |||
} | |||
.act-test { | |||
color: #2671E2; | |||
} | |||
} | |||
.close { | |||
opacity: 1; | |||
} | |||
} | |||
.slidebox { | |||
flex-shrink: 0; | |||
display: flex; | |||
align-items: center; | |||
.slide-img { | |||
width: 32rpx; | |||
height: 8rpx; | |||
} | |||
} | |||
/deep/ .uni-slider-tap-area { | |||
padding: 0; | |||
} | |||
/deep/ .uni-slider-wrapper { | |||
min-height: 0; | |||
} | |||
/deep/ .uni-slider-handle-wrapper { | |||
height: 6px; | |||
} | |||
.audio-slider { | |||
flex-grow: 1; | |||
} | |||
.play { | |||
width: 48rpx; | |||
height: 48rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
&.loading { | |||
width: 48rpx; | |||
height: 48rpx; | |||
animation: rotating_theme3 2s linear infinite; | |||
} | |||
} | |||
} | |||
.audio-flex { | |||
padding: 0 32rpx 0 0; | |||
flex-grow: 1; | |||
display: flex; | |||
align-items: center; | |||
text { | |||
color: #70798D; | |||
} | |||
} | |||
@keyframes rotating { | |||
0% { | |||
transform: rotateZ(0deg) | |||
} | |||
100% { | |||
transform: rotateZ(360deg) | |||
} | |||
} | |||
@keyframes rotating_theme3 { | |||
0% { | |||
transform: translate(-50%, -50%) rotateZ(0deg) | |||
} | |||
100% { | |||
transform: translate(-50%, -50%) rotateZ(360deg) | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,87 @@ | |||
import { | |||
mapState, | |||
mapActions, | |||
mapMutations | |||
} from 'vuex' | |||
export const audios = { | |||
data() { | |||
return { | |||
isBgPlay: false, // 是否禁止拖拽进度条 | |||
} | |||
}, | |||
computed: { | |||
...mapState(['bgAudioMannager']), | |||
}, | |||
methods: { | |||
setAudio(obj) { | |||
this.bgAudioMannager.title = '录音音频'; | |||
this.bgAudioMannager.src = obj.src | |||
this.bgAudioMannager.startTime = obj.currentTime | |||
}, | |||
setAudioFunc() { | |||
this.bgAudioMannager.onCanplay(() => { | |||
console.log('可以播放'); | |||
}); | |||
this.bgAudioMannager.onStop(() => { | |||
console.log('停止播放'); | |||
this.isBgPlay = false | |||
}); | |||
this.bgAudioMannager.onPause(() => { | |||
console.log('暂停播放'); | |||
this.isBgPlay = false | |||
// 设置当前暂停的视频播放位置 | |||
// this.seek(this.bgAudioMannager.currentTime) | |||
// this.play() | |||
}); | |||
this.bgAudioMannager.onEnded(() => { | |||
console.log('自然播放结束事件'); | |||
this.isBgPlay = false | |||
}); | |||
this.bgAudioMannager.onError((res) => { | |||
console.log(res.errMsg); | |||
console.log(res.errCode); | |||
}); | |||
this.bgAudioMannager.onTimeUpdate(() => { | |||
this.isBgPlay = true | |||
this.duration = this.bgAudioMannager.duration; | |||
this.currentTime = this.bgAudioMannager.currentTime; | |||
this.$emit('timeUpdate', { | |||
duration: this.bgAudioMannager.duration, | |||
currentTime: this.bgAudioMannager.currentTime | |||
}) | |||
}); | |||
}, | |||
// 背景音频暂停 | |||
audioPause() { | |||
this.bgAudioMannager.pause() | |||
}, | |||
// 背景音频播放 | |||
audioPlay() { | |||
this.pause() | |||
this.bgAudioMannager.play() | |||
}, | |||
//背景音频指定秒数播放 | |||
audioSeek(t) { | |||
this.bgAudioMannager.seek(t) | |||
}, | |||
// 停止背景音频播放 | |||
stopAduio() { | |||
console.log(this.bgAudioMannager) | |||
this.bgAudioMannager.pause() | |||
if (this.bgAudioMannager && this.bgAudioMannager.src) { | |||
this.bgAudioMannager.src = '' | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,119 @@ | |||
@mixin textoverflow() { | |||
display: -webkit-box; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 1; | |||
} | |||
@keyframes rowup { | |||
0% { | |||
-webkit-transform: translate(-50%, -50%) rotate(0deg); | |||
transform-origin: center center; | |||
} | |||
100% { | |||
-webkit-transform: translate(-50%, -50%) rotate(360deg); | |||
transform-origin: center center; | |||
} | |||
} | |||
.imt-audio{ | |||
position:relative; | |||
width: 100%; | |||
display: flex; | |||
box-sizing: border-box; | |||
background: #fff; | |||
overflow: hidden; | |||
.top { | |||
width: 140rpx; | |||
position: relative; | |||
} | |||
.audio-wrapper { | |||
display: flex; | |||
flex-direction: column; | |||
flex: 1; | |||
color: #fff; | |||
margin-left: 20rpx; | |||
} | |||
.slidebox { | |||
display: flex; | |||
justify-content: space-between; | |||
width: 96%; | |||
} | |||
/deep/ .uni-slider-tap-area { | |||
padding: 0; | |||
} | |||
/deep/ .uni-slider-wrapper { | |||
min-height: 0; | |||
} | |||
/deep/ .uni-slider-handle-wrapper { | |||
height: 6px; | |||
} | |||
.audio-slider { | |||
padding-top: 10rpx; | |||
margin-left: 150rpx; | |||
position: absolute; | |||
bottom: 40rpx; | |||
width: 75vw; | |||
left: 0; | |||
padding: 0; | |||
} | |||
// .cover { | |||
// width: 120rpx; | |||
// height: 120rpx; | |||
// box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); | |||
// position: absolute; | |||
// top: 50%; | |||
// left: 50%; | |||
// transform: translate(-50%, -50%); | |||
// animation-fill-mode: forwards; | |||
// -webkit-animation-fill-mode: forwards; | |||
// } | |||
.play { | |||
width: 48rpx; | |||
height: 48rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
&.loading{ | |||
width: 48rpx; | |||
height: 48rpx; | |||
animation: rotating_theme3 2s linear infinite; | |||
} | |||
} | |||
} | |||
@keyframes rotating { | |||
0% { | |||
transform: rotateZ(0deg) | |||
} | |||
100% { | |||
transform: rotateZ(360deg) | |||
} | |||
} | |||
@keyframes rotating_theme3 { | |||
0% { | |||
transform: translate(-50%, -50%) rotateZ(0deg) | |||
} | |||
100% { | |||
transform: translate(-50%, -50%) rotateZ(360deg) | |||
} | |||
} | |||
.hItem | |||
{ | |||
margin-left: 16rpx; | |||
} | |||
.extrButton | |||
{ | |||
font-size: 36rpx; | |||
} |
@@ -0,0 +1,432 @@ | |||
<template> | |||
<view class="imt-audio"> | |||
<template> | |||
<view class="top"> | |||
<view class="audio-control-wrapper"> | |||
<image :src="require('./static/loading.png')" v-if="playState=='loading'" class="play loading"> | |||
</image> | |||
<template v-else> | |||
<image :src="require('./static/playbtn.png')" alt="play" @click="play" class="play" | |||
v-if="playState=='pause'"></image> | |||
<image :src="require('./static/pausebtn.png')" alt="pause" @click="pause" class="play" v-else> | |||
</image> | |||
</template> | |||
</view> | |||
</view> | |||
<view class="audio-wrapper"> | |||
<view class="audio-flex"> | |||
<text> | |||
{{formatSeconds(currentTime)}} | |||
</text> | |||
<slider class="audio-slider" block-size="12" :max="duration" :value="currentTime" | |||
@change="sliderChange" @changing="sliderChanging"></slider> | |||
<text> | |||
{{formatSeconds(duration)}} | |||
</text> | |||
</view> | |||
<view class="slidebox" @click="showTip"> | |||
<slot name="extraCtrls"> | |||
<image class="slide-img" :src="require('./static/backimg.png')" mode=""></image> | |||
</slot> | |||
</view> | |||
<!-- 后台播放按钮区域 --> | |||
<view class="popup" v-if="show" :class="{close: closeing}" @click="checkPlayer"> | |||
<template v-if="!isBgPlay"> | |||
<image :src="require('./static/bg.png')" mode=""></image> | |||
</template> | |||
<template v-else> | |||
<image :src="require('./static/bg_act.png')" mode=""></image> | |||
</template> | |||
<text :class="{'act-test': isBgPlay}">后台播放</text> | |||
</view> | |||
</view> | |||
<!--video在ios中不能完全隐藏,否则无法播放--> | |||
<video id="videoPlayer" :autoplay="true" class="videoPlayer" :src="src" :muted="false" | |||
style="width: 10rpx;height:10rpx;" @play="playerOnPlay" @pause="playerOnPause" @ended="playerOnEnded" | |||
@timeupdate="playerOnTimeupdate" @waiting="playerOnWaiting" @error="playerOnError"></video> | |||
</template> | |||
</view> | |||
</template> | |||
<script> | |||
/* | |||
createInnerAudioContext()是audio组件的内部实现,不能熄屏播放、不能后台播放、不能倍速播放。 | |||
getBackgroundAudioManager() 可以熄屏播放、后台播放,不能倍速播放。缺点是响应速度很慢,无法实现精细、及时的进度控制,而且可能被别的程序占用。 | |||
因此这里只能用video来实现,video能倍速播放,不能熄屏播放、不能后台播放。而且避免了用createInnerAudioContext()实现的跳转到别的页面,还在播放的问题 | |||
因此应用程序可以在需要后台播放的时候(需要用户操作触发),再暂停这个控件的播放,然后自己用getBackgroundAudioManager实现后台播放 | |||
*/ | |||
import Vue from 'vue'; | |||
import { | |||
mapMutations | |||
} from 'vuex' | |||
import { | |||
audios | |||
} from './audioBg.js' | |||
export default { | |||
mixins: [audios], | |||
props: { | |||
nowFileTime: { | |||
type: [String, Number], | |||
default: 0 | |||
}, | |||
}, | |||
watch: { | |||
nowFileTime(oValue, nValue) { | |||
this.duration = nValue | |||
} | |||
}, | |||
data() { | |||
return { | |||
src: '', // | |||
poster: "", | |||
name: "...", | |||
singer: "...", | |||
duration: 0, | |||
currentTime: 0, | |||
playState: "pause", //"loading"/"playing"/"pause" | |||
isSliderChanging: false, | |||
isFirst: false, // 是否阻止第一次赋值 | |||
audio: null, // 音频对象 | |||
show: false, // 控制展示用的 | |||
closeing: false, // 默认关闭 | |||
}; | |||
}, | |||
created() { | |||
// 自定义组件,需要传递第二个参数为this,否则后续的pause等操作不起作用 | |||
this.videoCtx = uni.createVideoContext("videoPlayer", this); | |||
this.audio = uni.createInnerAudioContext(); | |||
this.audio.autoplay = false; | |||
this.createAudio() | |||
this.setAudioFunc() | |||
}, | |||
mounted() { | |||
this.audio.onCanplay((e) => { | |||
if (this.audio.duration != 0) { | |||
this.playState = "pause" | |||
this.$forceUpdate() | |||
} | |||
}) | |||
}, | |||
methods: { | |||
...mapMutations(['createAudio', 'stopAduio']), | |||
setSrc(value) { | |||
console.log(this, ' 我打印this') | |||
this.src = value; | |||
console.log(this.src, '我在这儿里更换src') | |||
// 获取当前音频的总时长 | |||
this.audio.src = value; | |||
}, | |||
setPoster(value) { | |||
this.poster = value; | |||
}, | |||
setName(value) { | |||
this.name = value; | |||
}, | |||
setSinger(value) { | |||
this.singer = value; | |||
}, | |||
playerOnPlay(e) { | |||
this.playState = "playing"; | |||
console.log('playerOnPlay', e) | |||
this.$emit("play"); | |||
}, | |||
playerOnPause(e) { | |||
this.playState = "pause"; | |||
console.log('playerOnPause', e) | |||
this.$emit("pause"); | |||
}, | |||
playerOnEnded(e) { | |||
this.playState = "pause"; | |||
console.log('playerOnEnded', e) | |||
this.$emit("ended"); | |||
}, | |||
playerOnTimeupdate(e) { | |||
if (this.isFirst) this.playState = "playing"; | |||
this.isFirst = true | |||
this.duration = e.detail.duration; | |||
this.currentTime = e.detail.currentTime; | |||
this.$emit("timeUpdate", e.detail); | |||
}, | |||
playerOnWaiting(e) { | |||
this.playState = "loading"; | |||
console.log('playerOnWaiting', e) | |||
}, | |||
playerOnError(e) { | |||
console.log('playerOnError', e) | |||
this.playState = "pause"; | |||
this.$emit("error", e); | |||
}, | |||
formatSeconds(seconds) { | |||
var result = typeof seconds === "string" ? parseFloat(seconds) : seconds; | |||
if (isNaN(result)) return ""; | |||
let h = Math.floor(result / 3600) < 10 ? | |||
"0" + Math.floor(result / 3600) : | |||
Math.floor(result / 3600); | |||
let m = Math.floor((result / 60) % 60) < 10 ? | |||
"0" + Math.floor((result / 60) % 60) : | |||
Math.floor((result / 60) % 60) + h * 60; | |||
let s = Math.floor(result % 60) < 10 ? | |||
"0" + Math.floor(result % 60) : | |||
Math.floor(result % 60); | |||
return `${h}:${m}:${s}`; | |||
}, | |||
stop() { | |||
this.videoCtx.stop(); | |||
}, | |||
seek(t) { | |||
this.videoCtx.seek(t); | |||
}, | |||
play() { | |||
// if (this.videoCtx.currentTime != this.videoCtx.currentTime) { | |||
// this.seek(this.currentTime) | |||
// } | |||
console.log('触发方法play') | |||
this.videoCtx.play(); //在有的H5浏览器里,如果play不是用户触发的,则play()会报错 | |||
// 暂停后台播放 | |||
this.stopAduio() | |||
}, | |||
pause() { | |||
console.log('触发方法pause') | |||
this.videoCtx.pause(); | |||
}, | |||
playbackRate(value) { | |||
this.videoCtx.playbackRate(value); | |||
//playbackRate不能在play之前或者之后立即调用,否则只有很少几率会成功 | |||
}, | |||
sliderChange(e) { | |||
this.isSliderChanging = false; | |||
//要通过e.detail.value获取,否则如果通过dom去读取slider的value | |||
//就会存在滚动条拖不动的情况 | |||
// this.videoCtx.seek(e.detail.value); | |||
let type = 'audio' | |||
if (this.bgAudioMannager.paused === false) { | |||
type = 'bgAudio' | |||
} | |||
this.$emit('sliderChangeComplate', { ...e, isType: type }) | |||
}, | |||
sliderChanging(e) { | |||
this.isSliderChanging = true; | |||
console.log(e, '当前正在改变') | |||
}, | |||
// 关闭后台播放按钮 | |||
closeTip() { | |||
this.closeing = false | |||
setTimeout(() => { | |||
this.show = false | |||
}, 250) | |||
}, | |||
// 展示后台播放按钮 | |||
showTip() { | |||
this.show = true | |||
setTimeout(() => { | |||
this.closeing = true | |||
}, 50) | |||
}, | |||
// 点击后台播放音频事件 | |||
backAudio() { | |||
this.pause() | |||
let obj = { | |||
src: this.src, | |||
currentTime: this.currentTime | |||
} | |||
this.setAudio(obj) | |||
}, | |||
// 切换播放源 | |||
checkPlayer() { | |||
this.closeTip() | |||
if (this.bgAudioMannager.paused === false) { | |||
this.stopAduio() | |||
} else { | |||
this.backAudio() | |||
} | |||
} | |||
}, | |||
} | |||
</script> | |||
<style lang="scss"> | |||
// @import './index.scss'; | |||
@mixin textoverflow() { | |||
display: -webkit-box; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 1; | |||
} | |||
@keyframes rowup { | |||
0% { | |||
-webkit-transform: translate(-50%, -50%) rotate(0deg); | |||
transform-origin: center center; | |||
} | |||
100% { | |||
-webkit-transform: translate(-50%, -50%) rotate(360deg); | |||
transform-origin: center center; | |||
} | |||
} | |||
.imt-audio { | |||
position: relative; | |||
width: 100%; | |||
height: 81rpx; | |||
display: flex; | |||
box-sizing: border-box; | |||
background: #fff; | |||
.top { | |||
position: relative; | |||
width: 100rpx; | |||
} | |||
.audio-wrapper { | |||
position: relative; | |||
padding: 0 20rpx; | |||
display: flex; | |||
flex: 1; | |||
color: #fff; | |||
.popup { | |||
position: absolute; | |||
right: 32rpx; | |||
top: -122rpx; | |||
z-index: 100; | |||
width: 136rpx; | |||
height: 122rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
flex-direction: column; | |||
background: #fff; | |||
border: 1rpx solid #E0E0E0; | |||
transition: all 0.25s linear; | |||
opacity: 0; | |||
image { | |||
width: 32rpx; | |||
height: 32rpx; | |||
} | |||
text { | |||
margin-top: 10rpx; | |||
color: #333; | |||
font-size: 24rpx; | |||
} | |||
.act-test { | |||
color: #2671E2; | |||
} | |||
} | |||
.close { | |||
opacity: 1; | |||
} | |||
} | |||
.slidebox { | |||
flex-shrink: 0; | |||
display: flex; | |||
align-items: center; | |||
.slide-img { | |||
width: 32rpx; | |||
height: 8rpx; | |||
} | |||
} | |||
/deep/ .uni-slider-tap-area { | |||
padding: 0; | |||
} | |||
/deep/ .uni-slider-wrapper { | |||
min-height: 0; | |||
} | |||
/deep/ .uni-slider-handle-wrapper { | |||
height: 6px; | |||
} | |||
.audio-slider { | |||
flex-grow: 1; | |||
} | |||
.play { | |||
width: 48rpx; | |||
height: 48rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
&.loading { | |||
width: 48rpx; | |||
height: 48rpx; | |||
animation: rotating_theme3 2s linear infinite; | |||
} | |||
} | |||
} | |||
.audio-flex { | |||
padding: 0 32rpx 0 0; | |||
flex-grow: 1; | |||
display: flex; | |||
align-items: center; | |||
text { | |||
color: #70798D; | |||
} | |||
} | |||
@keyframes rotating { | |||
0% { | |||
transform: rotateZ(0deg) | |||
} | |||
100% { | |||
transform: rotateZ(360deg) | |||
} | |||
} | |||
@keyframes rotating_theme3 { | |||
0% { | |||
transform: translate(-50%, -50%) rotateZ(0deg) | |||
} | |||
100% { | |||
transform: translate(-50%, -50%) rotateZ(360deg) | |||
} | |||
} | |||
.hItem { | |||
margin-left: 16rpx; | |||
} | |||
.extrButton { | |||
font-size: 36rpx; | |||
} | |||
.videoPlayer { | |||
position: absolute; | |||
left: 0; | |||
bottom: 0; | |||
z-index: -1; | |||
} | |||
</style> |
@@ -0,0 +1,84 @@ | |||
import { host, iMServiceHost } from './utils/domain.js' | |||
var config = { | |||
service: { | |||
host, | |||
iMServiceHost, | |||
getStage:`${host}/customer/getStage`, | |||
//验证toen | |||
verify:`${host}/user/verify`, | |||
//登录 | |||
login: `${host}/user/login`, | |||
//获取用户信息 | |||
getUser: `${host}/user/getUser`, | |||
//获取权限 | |||
getMenu:`${host}/user/getMenu`, | |||
//发送验证码 | |||
sendCode:`${host}/user/sendCode`, | |||
//验证码校验 | |||
plogin:`${host}/user/plogin`, | |||
//忘记密码 | |||
forgotPassword:`${host}/user/forgotPassword`, | |||
//修改密码 | |||
updatePassword: `${host}/user/resetPwd`, | |||
//修改用户信息 | |||
upload: `${host}/user/update`, | |||
// 上传头像 | |||
uploadHeadImg:`${host}/user/uploadHeadPortrait`, | |||
//分点学习标签 | |||
findSelectedLabel:`${host}/addtodigest/findSelectedLabel`, | |||
//获取全部学习 | |||
findAllZATD:`${host}/addtodigest/findAllZATD`, | |||
//查询点赞列表 | |||
likegetLike:`${host}/like/getLike`, | |||
// 获取评论 | |||
cmmentList:`${host}/comment/list`, | |||
// 新增评论 | |||
saveCmment:`${host}/comment/saveCmment`, | |||
// 新增文件评论 | |||
saveCmmentUpload:`${host}/comment/upload`, | |||
// 点赞 | |||
saveLike:`${host}/like/saveLike`, | |||
// 取消点赞 | |||
cancelLike:`${host}/like/cancelLike`, | |||
//同音转译接口3 | |||
getCorpusAnal: `${host}/corpus/splicAudioPlay`, | |||
//转写内容获取快进时间是第几个文件 | |||
fastForward:`${host}/corpus/fastForward`, | |||
//标记顾问 | |||
markConsultant:`${host}/corpus/markConsultant`, | |||
//同音转译接口 | |||
getSpeechAnalysis: `${host}/cms/mobile/getBytargetId`, | |||
//同音转译接口2 | |||
getCorpusAnalysis: `${host}/corpus/audioPlay`, | |||
//查询设备电量 | |||
findElectricity:`${host}/equipment/findElectricity`, | |||
//首页设备查询 | |||
findEquipmentState:`${host}/cusLvStatistics/findEquipmentState`, | |||
//首页实时统计 | |||
realTimeStatistics:`${host}/cusLvStatistics/realTimeStatistics`, | |||
//首页本周工作 | |||
workThisWeek:`${host}/cusLvStatistics/workThisWeek`, | |||
//查询是否开启选择顾问权限 | |||
getSelfAssignedByHouseId:`${host}/user/getSelfAssignedByHouseId`, | |||
//确认加精 | |||
addATD:`${host}/addtodigest/addATD`, | |||
//取消加精 | |||
delATD:`${host}/addtodigest/delATD`, | |||
// 获取客户来源列表 | |||
sourceList: `${host}/customer/sourceList`, | |||
// 升级公告 | |||
updateList: `${host}/zkMessage/messageList`, | |||
// 升级公告更新阅读 | |||
updateRead: `${host}/zkMessage/updateFlag`, | |||
// 隐私协议 | |||
privacyAgr: `${host}/zkPrivate/findById`, | |||
//首页更新弹框 | |||
updatePopup: `${host}/zkMessage/showMessage`, | |||
//首页首次更新弹框 | |||
firstShowPopup: `${host}/zkMessage/firstShow`, | |||
//消息未读数 | |||
notReadNum: `${host}/zkMessage/findFlagCount`, | |||
} | |||
}; | |||
module.exports = config; |
@@ -0,0 +1,39 @@ | |||
import Vue from 'vue'; | |||
import App from './App'; | |||
import dayjs from './utils/dayjs.min.js' | |||
import store from './store/index.js' | |||
import ZAudio from '@/components/uniapp-zaudio/index.js' | |||
Vue.config.productionTip = false; | |||
let zaudio = new ZAudio({ | |||
continuePlay: false, //续播 | |||
autoPlay: false, // 自动播放 部分浏览器不支持 | |||
}) | |||
Vue.prototype.$zaudio = zaudio | |||
Vue.prototype.$dayjs = dayjs; | |||
Vue.prototype.$store = store; | |||
import common from 'utils/common.js' | |||
Vue.prototype.$noMultipleClicks = common.noMultipleClicks; | |||
// 引入全局uView | |||
import uView from 'uview-ui' | |||
Vue.use(uView); | |||
import http from '@/utils/http.js' | |||
Vue.use(http, app) | |||
App.mpType = 'app'; | |||
const app = new Vue({ | |||
...App, | |||
store | |||
}); | |||
app.$mount(); |
@@ -0,0 +1,131 @@ | |||
{ | |||
"name" : "去房智控管家", | |||
"appid" : "__UNI__D88F14A", | |||
"description" : "AI营销助理", | |||
"versionName" : "1.1.0", | |||
"versionCode" : "100", | |||
"transformPx" : false, | |||
"app-plus" : { | |||
"usingComponents" : true, | |||
"nvueCompiler" : "uni-app", | |||
"compilerVersion" : 3, | |||
"splashscreen" : { | |||
"alwaysShowBeforeRender" : true, | |||
"waiting" : true, | |||
"autoclose" : true, | |||
"delay" : 0 | |||
}, | |||
"modules" : { | |||
"Push" : {}, | |||
"UIWebview" : {}, | |||
"Webview-x5" : {} | |||
}, | |||
"distribute" : { | |||
"android" : { | |||
"permissions" : [ | |||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", | |||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", | |||
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>", | |||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", | |||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>", | |||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", | |||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", | |||
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>", | |||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", | |||
"<uses-permission android:name=\"android.permission.CAMERA\"/>", | |||
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>", | |||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", | |||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>", | |||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", | |||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", | |||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", | |||
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>", | |||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", | |||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", | |||
"<uses-feature android:name=\"android.hardware.camera\"/>", | |||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", | |||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" | |||
], | |||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ] | |||
}, | |||
"ios" : { | |||
"idfa" : false | |||
}, | |||
"sdkConfigs" : { | |||
"ad" : {}, | |||
"oauth" : {} | |||
}, | |||
"icons" : { | |||
"android" : { | |||
"hdpi" : "unpackage/res/icons/72x72.png", | |||
"xhdpi" : "unpackage/res/icons/96x96.png", | |||
"xxhdpi" : "unpackage/res/icons/144x144.png", | |||
"xxxhdpi" : "unpackage/res/icons/192x192.png" | |||
}, | |||
"ios" : { | |||
"appstore" : "unpackage/res/icons/1024x1024.png", | |||
"ipad" : { | |||
"app" : "unpackage/res/icons/76x76.png", | |||
"app@2x" : "unpackage/res/icons/152x152.png", | |||
"notification" : "unpackage/res/icons/20x20.png", | |||
"notification@2x" : "unpackage/res/icons/40x40.png", | |||
"proapp@2x" : "unpackage/res/icons/167x167.png", | |||
"settings" : "unpackage/res/icons/29x29.png", | |||
"settings@2x" : "unpackage/res/icons/58x58.png", | |||
"spotlight" : "unpackage/res/icons/40x40.png", | |||
"spotlight@2x" : "unpackage/res/icons/80x80.png" | |||
}, | |||
"iphone" : { | |||
"app@2x" : "unpackage/res/icons/120x120.png", | |||
"app@3x" : "unpackage/res/icons/180x180.png", | |||
"notification@2x" : "unpackage/res/icons/40x40.png", | |||
"notification@3x" : "unpackage/res/icons/60x60.png", | |||
"settings@2x" : "unpackage/res/icons/58x58.png", | |||
"settings@3x" : "unpackage/res/icons/87x87.png", | |||
"spotlight@2x" : "unpackage/res/icons/80x80.png", | |||
"spotlight@3x" : "unpackage/res/icons/120x120.png" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"quickapp" : {}, | |||
"mp-weixin" : { | |||
"appid" : "wx8f883dca5ecc5510", | |||
"setting" : { | |||
"urlCheck" : false, | |||
"es6" : true, | |||
"postcss" : true, | |||
"minified" : true | |||
}, | |||
"usingComponents" : true, | |||
"permission" : {}, | |||
"requiredBackgroundModes" : [ "audio" ], | |||
"plugins" : { | |||
"WechatSI" : { | |||
"version" : "0.3.4", | |||
"provider" : "wx069ba97219f66d99" | |||
} | |||
}, | |||
"uniStatistics" : { | |||
"enable" : true | |||
} | |||
}, | |||
"mp-alipay" : { | |||
"usingComponents" : true | |||
}, | |||
"mp-baidu" : { | |||
"usingComponents" : true | |||
}, | |||
"mp-toutiao" : { | |||
"usingComponents" : true, | |||
"uniStatistics" : { | |||
"enable" : false | |||
} | |||
}, | |||
"h5" : { | |||
"router" : { | |||
"base" : "/pages/login/guide" | |||
} | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
{ | |||
"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==" | |||
} | |||
} | |||
} |
@@ -0,0 +1,625 @@ | |||
{ | |||
"easycom": { | |||
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue" | |||
}, | |||
//这个pages里只放这五个页面,新增页面时请对应的放到下面的分包里 | |||
"pages": [ | |||
// { | |||
// "path": "pages/mine/registerForm", | |||
// "style": { | |||
// "navigationBarTitleText": "访客登记表", | |||
// "navigationBarBackgroundColor": "#2671E2", | |||
// "navigationBarTextStyle": "white" | |||
// } | |||
// }, | |||
// { | |||
// "path": "pages/mine/registerResult", | |||
// "style": { | |||
// "navigationBarTitleText": "访客登记表", | |||
// "navigationBarBackgroundColor": "#2671E2", | |||
// "navigationBarTextStyle": "white" | |||
// } | |||
// }, | |||
{ | |||
"path": "pages/index/guide", | |||
"style": { | |||
"navigationBarBackgroundColor": "#008EF2", | |||
"navigationBarTextStyle": "white", | |||
"navigationStyle": "custom" | |||
} | |||
}, | |||
{ | |||
"path": "pages/index/index", | |||
"style": { | |||
"navigationBarTitleText": "智控管家", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "pages/index/customer", | |||
"style": { | |||
"navigationBarTitleText": "接待", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white" | |||
} | |||
}, { | |||
"path": "pages/index/learning", | |||
"style": { | |||
"navigationBarTitleText": "学习", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white", | |||
"enablePullDownRefresh": true | |||
} | |||
}, { | |||
"path": "pages/index/personal", | |||
"style": { | |||
"navigationBarTitleText": "我的", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white" | |||
} | |||
}, | |||
{ | |||
"path": "pages/reportExcel/dayReport", | |||
"style": { | |||
"navigationBarTitleText": "数智工牌日报", | |||
"navigationBarBackgroundColor": "#ffffff", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "pages/reportExcel/weekReport", | |||
"style": { | |||
"navigationBarTitleText": "数智工牌周报", | |||
"navigationBarBackgroundColor": "#ffffff", | |||
"navigationBarTextStyle": "black" | |||
} | |||
} | |||
], | |||
//这下面是分包 | |||
"subPackages": [{ | |||
"root": "pages/login", //登录相关 | |||
"name": "login", | |||
"pages": [{ | |||
"path": "index" | |||
}, | |||
{ | |||
"path": "Verification", | |||
"style": { | |||
"navigationBarTitleText": "验证码登录", | |||
"navigationBarBackgroundColor": "#008EF2", | |||
"navigationBarTextStyle": "white", | |||
"navigationStyle": "custom" | |||
} | |||
}, | |||
{ | |||
"path": "yinzhongmalogin", | |||
"style": { | |||
"navigationBarTitleText": "验证码登录", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Setthepassword", | |||
"style": { | |||
"navigationBarTitleText": "设置密码", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Verifythelogin", | |||
"style": { | |||
"navigationBarTitleText": "验证码登录", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
} | |||
] | |||
}, | |||
{ | |||
"root": "pages/mine", //个人中心 | |||
"name": "mine", | |||
"pages": [{ | |||
"path": "details", | |||
"style": { | |||
"navigationBarTitleText": "详情", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "details2", | |||
"style": { | |||
"navigationBarTitleText": "详情", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "detailsNew", | |||
"style": { | |||
"navigationBarTitleText": "详情", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "calibration", | |||
"style": { | |||
"navigationBarTitleText": "校验", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "ScoringPlaylist", | |||
"style": { | |||
"navigationBarTitleText": "匹配标签", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Myprofile", | |||
"style": { | |||
"navigationBarTitleText": "编辑资料", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "nickname", | |||
"style": { | |||
"navigationBarTitleText": "编辑昵称", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "signature", | |||
"style": { | |||
"navigationBarTitleText": "编辑签名", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Changehepassword", | |||
"style": { | |||
"navigationBarTitleText": "修改密码", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "subscribe", | |||
"style": { | |||
"navigationBarTitleText": "消息订阅", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "reception/addreception", | |||
"style": { | |||
"navigationBarTitleText": "新增接待", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "reception/consultant", | |||
"style": { | |||
"navigationBarTitleText": "选择顾问", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "consultanonduty/index", | |||
"style": { | |||
"navigationBarTitleText": "值班顾问", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "equipment/index", | |||
"style": { | |||
"navigationBarTitleText": "设备管理", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "messageList", | |||
"style": { | |||
"navigationBarTitleText": "消息", | |||
"navigationBarBackgroundColor": "#ffffff", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, { | |||
"path": "selectBuilding", | |||
"style": { | |||
"navigationBarTitleText": "切换项目", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, { | |||
"path": "registerCode", | |||
"style": { | |||
"navigationBarTitleText": "访客登记码", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white" | |||
} | |||
}, { | |||
"path": "registerForm", | |||
"style": { | |||
"navigationBarTitleText": "访客登记表", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white" | |||
} | |||
}, | |||
{ | |||
"path": "registerResult", | |||
"style": { | |||
"navigationBarTitleText": "访客登记表", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white" | |||
} | |||
}, { | |||
"path": "messageDetail", | |||
"style": { | |||
"navigationBarTitleText": "公告详情", | |||
"navigationBarBackgroundColor": "#2671E2", | |||
"navigationBarTextStyle": "white" | |||
} | |||
}, { | |||
"path": "messageDetails", | |||
"style": { | |||
"navigationBarTitleText": "隐私协议", | |||
"navigationBarBackgroundColor": "#fff", | |||
"navigationBarTextStyle": "black" | |||
} | |||
} | |||
] | |||
}, | |||
{ | |||
"root": "pages/learning", //学习 | |||
"name": "learning", | |||
"pages": [{ | |||
"path": "Thefulltext/index", | |||
"style": { | |||
"navigationBarTitleText": "全文学习", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Thefulltext/index2", | |||
"style": { | |||
"navigationBarTitleText": "全文学习", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Thefulltext/search", | |||
"style": { | |||
"navigationBarTitleText": "搜索", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Keywordsearch", | |||
"style": { | |||
"navigationBarTitleText": "搜索", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Equinoctiallearning", | |||
"style": { | |||
"navigationBarTitleText": "分点学习", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "Equinoctial/index", | |||
"style": { | |||
"navigationBarTitleText": "分点学习", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Equinoctial/index2", | |||
"style": { | |||
"navigationBarTitleText": "分点学习", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
} | |||
] | |||
}, | |||
{ | |||
"root": "pages/center", //中心逻辑的模块都放到这里 | |||
"name": "center", | |||
"pages": [{ | |||
"path": "Piabodata/index", | |||
"style": { | |||
"navigationBarTitleText": "销讲数据", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/Groupcontrast", | |||
"style": { | |||
"navigationBarTitleText": "集团对比", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/Theteamcompared", | |||
"style": { | |||
"navigationBarTitleText": "团队对比", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/selectTeam", | |||
"style": { | |||
"navigationBarTitleText": "选择团队", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/selectGroup", | |||
"style": { | |||
"navigationBarTitleText": "选择项目", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/Userinsightinto", | |||
"style": { | |||
"navigationBarTitleText": "客户画像", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/TrendAnalysis", | |||
"style": { | |||
"navigationBarTitleText": "趋势分析", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/StaffAnalysis", | |||
"style": { | |||
"navigationBarTitleText": "员工分析", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/Customerportrait/Detailsofthesearch", | |||
"style": { | |||
"navigationBarTitleText": "搜索", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/Customerportrait/Receivedetailabout", | |||
"style": { | |||
"navigationBarTitleText": "详情", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/Customerportrait/Receivingrecords", | |||
"style": { | |||
"navigationBarTitleText": "列表", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "Piabodata/Employeesstatistics", | |||
"style": { | |||
"navigationBarTitleText": "顾问排名", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "records/index", | |||
"style": { | |||
"navigationBarTitleText": "接待记录", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "records/recordSearch", | |||
"style": { | |||
"navigationBarTitleText": "搜索", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "prohibited/index", | |||
"style": { | |||
"navigationBarTitleText": "违禁记录", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "prohibited/details", | |||
"style": { | |||
"navigationBarTitleText": "违禁详情", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": false | |||
} | |||
}, | |||
{ | |||
"path": "consumer/index", | |||
"style": { | |||
"navigationBarTitleText": "客户管理", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black", | |||
"enablePullDownRefresh": true | |||
} | |||
}, | |||
{ | |||
"path": "consumer/consumerSearch", | |||
"style": { | |||
"navigationBarTitleText": "搜索", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "consumer/consumerDetail", | |||
"style": { | |||
"navigationBarTitleText": "客户详情", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "consumer/remind", | |||
"style": { | |||
"navigationBarTitleText": "添加提醒", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "consumer/edit", | |||
"style": { | |||
"navigationBarTitleText": "编辑客户", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
}, | |||
{ | |||
"path": "consumer/newFollowup/newFollowup", | |||
"style": { | |||
"navigationBarTitleText": "写跟进", | |||
"navigationBarBackgroundColor": "#FFFFFF", | |||
"navigationBarTextStyle": "black" | |||
} | |||
} | |||
] | |||
} | |||
], | |||
"permission": { | |||
"scope.userLocation": { | |||
"desc": "你的位置信息将用于小程序位置接口的效果展示" | |||
} | |||
}, | |||
"networkTimeout": { | |||
"request": 10000, | |||
"downloadFile": 10000 | |||
}, | |||
"debug": false, | |||
"tabBar": { | |||
"color": "#8E8E8E", | |||
"selectedColor": "#1296db", | |||
"borderStyle": "white", | |||
"list": [{ | |||
"pagePath": "pages/index/index" | |||
// "iconPath": "/static/images/tabBar/home.png", | |||
// "selectedIconPath": "/static/images/tabBar/homeActive.png", | |||
// "text": "首页" | |||
}, | |||
{ | |||
"pagePath": "pages/index/customer" | |||
// "iconPath": "/static/images/tabBar/customer.png", | |||
// "selectedIconPath": "/static/images/tabBar/customerActive.png", | |||
// "text": "接待" | |||
}, | |||
{ | |||
"pagePath": "pages/index/learning" | |||
// "iconPath": "/static/images/tabBar/voice.png", | |||
// "selectedIconPath": "/static/images/tabBar/voiceActive.png", | |||
// "text": "学习" | |||
}, | |||
{ | |||
"pagePath": "pages/index/personal" | |||
// "iconPath": "/static/images/tabBar/user.png", | |||
// "selectedIconPath": "/static/images/tabBar/userActive.png", | |||
// "text": "个人" | |||
} | |||
] | |||
}, | |||
"sitemapLocation": "sitemap.json", | |||
"globalStyle": { | |||
"backgroundColor": "#F6F6F6", | |||
"backgroundTextStyle": "dark", | |||
"navigationBarBackgroundColor": "#fff", | |||
"navigationBarTitleText": "数智工牌", | |||
"navigationBarTextStyle": "black" | |||
}, | |||
"condition" : { //模式配置,仅开发期间生效 | |||
"current": 0, //当前激活的模式(list 的索引项) | |||
"list": [ | |||
{ | |||
"name": "访客二维码", //模式名称 | |||
"path": "pages/mine/registerForm", //启动页面,必选 | |||
"query": "" //启动参数,在页面的onLoad函数里面得到 | |||
} | |||
] | |||
} | |||
} |
@@ -0,0 +1,186 @@ | |||
<template> | |||
<view class="translation"> | |||
<view style="display: flex;width: 100%;height: 100rpx;border-bottom: 1px solid #E0E0E0;"> | |||
<view style="width: 50%;display: flex;align-items: center;justify-content: center;font-size: 30rpx;"> | |||
<view style="line-height: 50rpx;" :class="roleindex == 0 ? 'bosdttom' : ''" @click="tapspagek(0)"> | |||
画像语义词选择</view> | |||
</view> | |||
<view style="width: 50%;display: flex;align-items: center;justify-content: center;font-size: 30rpx;"> | |||
<view style="line-height: 50rpx;" :class="roleindex == 1 ? 'bosdttom' : ''" @click="tapspagek(1)">关键词输入 | |||
</view> | |||
</view> | |||
</view> | |||
<view v-if='roleindex==0' style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;"> | |||
<view style="display: flex;align-items: center;border-bottom: 1px solid #C9C9C9;height: 80rpx;"> | |||
<view>画像语义词:</view> | |||
<view style="width:70%" @click="oninputtap()"> | |||
<text v-if="Semanticword.length==0">请选择</text> | |||
<text v-else>{{Semanticword}}</text> | |||
</view> | |||
<view> | |||
<image src="https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/qf/more.png" | |||
style="width:12rpx;height:23rpx;margin-left: 16rpx;"> | |||
</view> | |||
</view> | |||
</view> | |||
<view v-if='roleindex==1' style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;background: #F2F2F2;border-radius: 32rpx; | |||
display: flex;align-items: center;"> | |||
<view style="width: 10%;height: 64rpx;display: flex;align-items: center;"> | |||
<image style="width: 28rpx;height: 28rpx;margin-left: 30rpx;" src="/static/images/search.png" mode=""> | |||
</image> | |||
</view> | |||
<view style="width: 90%;height: 64rpx;display: flex;align-items: center;"> | |||
<input type="text" @input="searchinfo" v-model="keyword" placeholder="请输入关键字" | |||
style="width: 100%;color: #999999;font-size: 24rpx;" /> | |||
</view> | |||
</view> | |||
<view style="width: 690rpx;margin: 0 auto;margin-top: 10rpx;"> | |||
<view | |||
style="width: 100%;border-bottom: 1px solid #E0E0E0;display: flex;padding-bottom: 10rpx;margin-top: 40rpx;" | |||
v-for="(item,index) in listarr" :key='index' @click="toaidoinfo(item.Content,item.corpusId,item.index)"> | |||
<view style="width: 26rpx;height: 36rpx;margin-top: 4rpx;"> | |||
<image style="width: 26rpx;height: 28rpx;" src="/static/images/testimg.png" mode=""></image> | |||
</view> | |||
<view v-html="item.Content.text" | |||
style="color: #666666;font-size: 28rpx;line-height: 36rpx;margin-left: 10rpx;width: 80%;"></view> | |||
<view style="font-size: 28rpx;width: 10%;width: 14%;text-align: right;">{{item.Content.time}}</view> | |||
</view> | |||
</view> | |||
<u-select v-model="Showhiddenunits" mode="single-column" :list="selectlist" @confirm="confirm"></u-select> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../../../utils/util.js"); | |||
var config = require("../../../../config"); | |||
export default { | |||
data() { | |||
return { | |||
customerId: '', | |||
listarr: [], | |||
keyword: '', | |||
skpl: '', | |||
roleindex: 0, | |||
Showhiddenunits: false, | |||
selectlist: [], | |||
Semanticword: '', | |||
qujian: true, | |||
from: '', // 来源 | |||
}; | |||
}, | |||
onLoad(options) { | |||
this.customerId = options.customerId; | |||
this.statistical() | |||
}, | |||
methods: { | |||
statistical() { | |||
this.$u.get("/matchKeywords/findCARKeywords", { | |||
customerId: this.customerId | |||
}).then(res => { | |||
res.forEach((item, index) => { | |||
if (item.isInterval == 0) { | |||
item.label = item.name + item.unit + '-' + item.endName + item.unit; | |||
item.value = index | |||
} else { | |||
item.label = item.name; | |||
item.value = index | |||
} | |||
}) | |||
this.selectlist = res; | |||
}) | |||
}, | |||
oninputtap() { | |||
this.Showhiddenunits = true; | |||
}, | |||
confirm(e) { | |||
let indexs = e[0].value; | |||
this.selectlist.forEach((item, index) => { | |||
if (indexs == item.value) { | |||
this.Semanticword = item.name; | |||
this.keyword = item.matchName; | |||
if (item.isInterval == 0) { | |||
this.qujian = false; | |||
this.Semanticword = item.name + item.unit + '-' + item.endName + item.unit; | |||
} else { | |||
this.qujian = true; | |||
} | |||
} | |||
}) | |||
this.searchinfo() | |||
}, | |||
tapspagek(i) { | |||
this.roleindex = i; | |||
this.keyword = ""; | |||
this.Semanticword = ''; | |||
this.qujian = true; | |||
this.listarr = []; | |||
}, | |||
formatTime(num) { | |||
//格式化时间格式 | |||
num = num.toFixed(0); | |||
let second = num % 60; | |||
if (second < 10) second = '0' + second; | |||
let min = Math.floor(num / 60); | |||
if (min < 10) min = '0' + min; | |||
return min + ":" + second; | |||
}, | |||
searchinfo() { | |||
if (this.keyword.length == 0) { | |||
return | |||
} else { | |||
let parames = { | |||
keyword: this.keyword, | |||
customerId: this.customerId | |||
} | |||
this.$u.post("/corpus/keyWordsMatching", parames).then(res => { | |||
res.forEach(item => { | |||
item.Content = JSON.parse(item.transferContent) | |||
}) | |||
res.forEach(cet => { | |||
cet.Content.time = this.formatTime(cet.Content.bg / 1000) | |||
if (this.qujian == false) { | |||
cet.Content.text = cet.Content.onebest; | |||
} else { | |||
cet.Content.text = this.brightKeyword(cet.Content.onebest) | |||
} | |||
}) | |||
this.listarr = res; | |||
}) | |||
} | |||
}, | |||
//替换方法 | |||
brightKeyword(val) { | |||
if (val.indexOf(this.keyword) !== -1) { | |||
return val.replace(this.keyword, `<font style='color: red'>${this.keyword}</font>`); | |||
} else { | |||
return val; | |||
} | |||
}, | |||
//跳转 | |||
toaidoinfo(item, id, index) { | |||
uni.setStorageSync("entrance", 2); //写入缓存 | |||
item.customerId = this.customerId; | |||
item.id = id; | |||
item.index = index; | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: item | |||
}); | |||
uni.$emit('Receivedetailabout', item) | |||
wx.navigateBack({ //然后返回上一个页面 | |||
delta: 1 | |||
}) | |||
} | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.bosdttom { | |||
border-bottom: 2px solid #2671E2; | |||
} | |||
</style> |
@@ -0,0 +1,717 @@ | |||
<template> | |||
<view class="cenbox"> | |||
<view class="screeningtop"> | |||
<view class="screeningview" @click="clickscreening(1)"> | |||
<view>近一周</view> | |||
<view class="viewimg"> | |||
<image v-if="screeningshow1==false" src="../../../../static/images/down1.png" mode=""></image> | |||
<image v-if="screeningshow1==true" src="../../../../static/images/down2.png" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="screeningview" @click="clickscreening(2)"> | |||
<view>客户</view> | |||
<view class="viewimg"> | |||
<image v-if="screeningshow2==false" src="../../../../static/images/down1.png" mode=""></image> | |||
<image v-if="screeningshow2==true" src="../../../../static/images/down2.png" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="screeningview" @click="clickscreening(3)"> | |||
<view>置业顾问</view> | |||
<view class="viewimg"> | |||
<image v-if="screeningshow3==false" src="../../../../static/images/down1.png" mode=""></image> | |||
<image v-if="screeningshow3==true" src="../../../../static/images/down2.png" mode=""></image> | |||
</view> | |||
</view> | |||
<view style="border: none;" class="screeningview" @click="clickscreening(4)"> | |||
<view>语义词</view> | |||
<view class="viewimg"> | |||
<image v-if="screeningshow4==false" src="../../../../static/images/down1.png" mode=""></image> | |||
<image v-if="screeningshow4==true" src="../../../../static/images/down2.png" mode=""></image> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="zhuti"> | |||
<view v-if="tadelist.length!=0" class="cenforview" v-for="(item,index) in tadelist" :key='index' @click="toinfo(item)"> | |||
<view class="cenfortop"> | |||
<view class="fortopzuo"> | |||
<view class="topzuoimg"> | |||
<image src="../../../../static/images/userorder.png" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="fortopyou"> | |||
<view class="topyouview1"> | |||
<view class="youview1-1">{{item.agentName}}</view> | |||
<view class="youview1-2">接待开始时间:{{item.staTime}}</view> | |||
</view> | |||
<view class="topyouview2">客户姓名:{{item.name}}</view> | |||
</view> | |||
</view> | |||
<view class="cenforbottom"> | |||
<view class="forbottomview"> | |||
<view class="bottomview1">录音时长 (分钟)</view> | |||
<view class="bottomview2">{{item.mm}}分钟</view> | |||
</view> | |||
<view class="forbottomview"> | |||
<view class="bottomview1">需求触达次数</view> | |||
<view class="bottomview2">{{item.total}}次</view> | |||
</view> | |||
<view class="forbottomview" style="border: none;"> | |||
<view class="bottomview1">接访得分</view> | |||
<view class="bottomview2" v-if="item.fraction==null">0分</view> | |||
<view class="bottomview2" v-else>{{item.fraction}}分</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view v-if="tadelist.length==0" style="width: 100%;height: 100%;display: flex;align-items: center;"> | |||
<view style="width: 100%;background: #FFFFFF;padding-top: 200rpx;"> | |||
<view style="width: 100%;text-align: center;"> | |||
<image style="width: 200rpx;height: 200rpx;" src="https://static.quhouse.com/zhikong_xcx_img/nodatalist.png" mode=""></image> | |||
</view> | |||
<view style="text-align: center;width: 100%;margin-top: 20rpx;color: #999999;">暂无数据</view> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 1 --> | |||
<view v-if="screeningshow1==true" class="call_zhezhao" @click="allcancel()"></view> | |||
<view v-if="screeningshow1==true" class="timepick"> | |||
<view class="tiempickbox"> | |||
<view :class="{ timeactive: activetime == 0 }" @click="activetimetab(0)">今日</view> | |||
<view :class="{ timeactive: activetime == 1 }" @click="activetimetab(1)">昨日</view> | |||
<view :class="{ timeactive: activetime == 2 }" @click="activetimetab(2)">近一周</view> | |||
<view :class="{ timeactive: activetime == 3 }" @click="activetimetab(3)">本月</view> | |||
</view> | |||
<view class="tiempickzidingyi" @click="activetimetab(5)"> | |||
<text v-if="Datesicing.length==0">自定义时间:请选择</text> | |||
<text v-else>{{Datesicing}}</text> | |||
</view> | |||
</view> | |||
<!-- 2 --> | |||
<view v-if="screeningshow2==true" class="call_zhezhao" @click="allcancel()"></view> | |||
<view v-if="screeningshow2==true" class="userinput"> | |||
<view class="inputdlex"> | |||
<view class="flexzuo"> | |||
<input class="flexinput" @confirm="searchinfo()" v-model="name" type="text" placeholder="请输入客户名" /> | |||
</view> | |||
<view class="flexyou" @click="searchinfo()">搜索</view> | |||
</view> | |||
</view> | |||
<!-- 3 --> | |||
<view v-if="screeningshow3==true" class="call_zhezhao" @click="allcancel()"></view> | |||
<view v-if="screeningshow3==true" class="userinput"> | |||
<view class="inputdlex"> | |||
<view class="flexzuo"> | |||
<input class="flexinput" @confirm="searchinfo()" v-model="agentName" type="text" placeholder="请输入顾问名" /> | |||
</view> | |||
<view class="flexyou" @click="searchinfo()">搜索</view> | |||
</view> | |||
</view> | |||
<!-- 4 --> | |||
<view v-if="screeningshow4==true" class="call_zhezhao" @click="allcancel()"></view> | |||
<view v-if="screeningshow4==true" class="yuyipick"> | |||
<view class="inputdlex"> | |||
<!-- <view :class="{ timeactive111: keywordsId == item.keywordsId }" @click="semantictap(index)" | |||
v-for="(item,index) in semanticlist" :key="index">{{item.name}}</view> --> | |||
<view :class="{ timeactive111: item.checked }" @click="itemChcek(index)" | |||
v-for="(item,index) in semanticlist" :key="index">{{item.name}}</view> | |||
</view> | |||
<view class="screen-foot"> | |||
<view class="screen-foot-reset" @click="reset"> | |||
重置 | |||
</view> | |||
<view class="screen-foot-sure" @click="screensure"> | |||
确定 | |||
</view> | |||
</view> | |||
</view> | |||
<u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> | |||
</view> | |||
</template> | |||
<script> | |||
var app = getApp(); | |||
var util = require("../../../../utils/util.js"); | |||
var config = require("../../../../config"); | |||
export default { | |||
data() { | |||
return { | |||
screeningshow1:false, | |||
screeningshow2:false, | |||
screeningshow3:false, | |||
screeningshow4:false, | |||
activetime:2, | |||
totalTimeShow:false, | |||
Datesicing:'', | |||
Inthemiddletime:'', | |||
starttime:'',//开始时间 | |||
endoftime:'',//结束时间 | |||
keywordsId:'',//选中语义词id | |||
houseId:'',//项目id | |||
semanticlist:[],//语义词集合 | |||
name:'', | |||
agentName:'', | |||
pageNum:1, | |||
pageSize:10, | |||
tadelist:[], | |||
totalpage:0, | |||
keywordIds:'', | |||
type:0, | |||
customerId: '', // 点击那一项的customerId | |||
}; | |||
}, | |||
onLoad(options) { | |||
console.log(options) | |||
if(options.datatype==3){ | |||
this.activetime=5; | |||
this.starttime=options.starttime; | |||
this.endoftime=options.endoftime; | |||
this.Datesicing=this.starttime+'至'+this.endoftime; | |||
}else{ | |||
this.activetime=options.datatype; | |||
this.starttime=''; | |||
this.endoftime=''; | |||
this.Datesicing=''; | |||
} | |||
// this.keywordsId=options.keywordsId | |||
this.keywordIds=options.keywordsId | |||
this.houseId=uni.getStorageSync('buildingID').id; | |||
this.Accesstolevel() | |||
}, | |||
onReachBottom() { | |||
if (this.totalpage < this.pageNum * this.pageSize) { | |||
return uni.showToast({ | |||
title: "到底了", | |||
}) | |||
} | |||
this.pageNum++; | |||
this.getinit(); | |||
}, | |||
methods: { | |||
toinfo(item){ | |||
let parames = { | |||
marketingId: this.keywordIds, | |||
customerId: item.id, | |||
type: '1' | |||
} | |||
this.$u.post("/corpus/pinWordMatching", parames).then(res => { | |||
let items = JSON.parse(res[0].transferContent) | |||
uni.setStorageSync("entrance", 1); //写入缓存 | |||
uni.navigateTo({ | |||
url: `/pages/center/Piabodata/Customerportrait/Receivedetailabout?customerId=${item.id}&info=${JSON.stringify(items)}` | |||
}) | |||
}).catch(e => { | |||
uni.setStorageSync("entrance", 1); //写入缓存 | |||
uni.navigateTo({ | |||
url: `/pages/center/Piabodata/Customerportrait/Receivedetailabout?customerId=${item.id}` | |||
}) | |||
}) | |||
}, | |||
//搜索 | |||
searchinfo(){ | |||
this.totalpage=0; | |||
this.tadelist=[]; | |||
this.pageNum=1; | |||
this.getinit() | |||
}, | |||
itemChcek(index){ | |||
this.semanticlist[index].checked=!this.semanticlist[index].checked | |||
this.$forceUpdate() | |||
}, | |||
reset(){ | |||
this.semanticlist.map(item=>{ | |||
item.checked=false | |||
}) | |||
this.keywordIds='' | |||
this.$forceUpdate() | |||
this.allcancel() | |||
this.totalpage=0; | |||
this.tadelist=[]; | |||
this.pageNum=1; | |||
this.getinit() | |||
}, | |||
screensure(){ | |||
let arr=[] | |||
this.semanticlist.map(item=>{ | |||
if(item.checked){ | |||
arr.push(item.keywordsId) | |||
} | |||
}) | |||
this.keywordIds=arr.join(',') | |||
// console.log(this.keywordIds) | |||
this.allcancel() | |||
this.totalpage=0; | |||
this.tadelist=[]; | |||
this.pageNum=1; | |||
this.getinit() | |||
}, | |||
//点击三级 | |||
semantictap(index){ | |||
this.keywordsId=this.semanticlist[index].keywordsId; | |||
this.allcancel() | |||
this.totalpage=0; | |||
this.tadelist=[]; | |||
this.pageNum=1; | |||
this.getinit() | |||
}, | |||
//获取列表数据 | |||
getinit(){ | |||
uni.showToast({ | |||
title: '加载中', | |||
icon:'loading', | |||
duration: 1500 | |||
}); | |||
let datatype=''; | |||
if(this.activetime==5){ | |||
var parames={ | |||
pageNum:this.pageNum, | |||
pageSize:this.pageSize, | |||
query:{ | |||
staTime:this.starttime, | |||
endTime:this.endoftime, | |||
time:1, | |||
name:this.name, | |||
agentName:this.agentName, | |||
type:this.type, | |||
keywordIds:this.keywordIds, | |||
// keywordsId:this.keywordsId, | |||
projectId:this.houseId, | |||
} | |||
} | |||
}else{ | |||
datatype=this.activetime; | |||
var parames={ | |||
pageNum:this.pageNum, | |||
pageSize:this.pageSize, | |||
query:{ | |||
dateType:Number(datatype), | |||
staTime:this.starttime, | |||
endTime:this.endoftime, | |||
time:1, | |||
name:this.name, | |||
agentName:this.agentName, | |||
type:0, | |||
keywordIds:this.keywordIds, | |||
// keywordsId:this.keywordsId, | |||
projectId:this.houseId, | |||
} | |||
} | |||
} | |||
this.$u.post("/matchKeywords/receptionRecord", parames).then(data => { | |||
this.type=1; | |||
if(data.results==null){ | |||
console.log("没有") | |||
return | |||
}else{ | |||
this.tadelist=[...this.tadelist, ...data.results]; | |||
this.totalpage=data.totalRecord; | |||
} | |||
}) | |||
}, | |||
//获取三级 | |||
Accesstolevel(){ | |||
let datatype=''; | |||
if(this.activetime==5){ | |||
var parames={ | |||
type:0, | |||
statDateStart:this.starttime, | |||
statDateEnd:this.endoftime, | |||
houseId:this.houseId | |||
} | |||
}else{ | |||
datatype=this.activetime; | |||
var parames={ | |||
type:0, | |||
dateType:Number(datatype), | |||
statDateStart:this.starttime, | |||
statDateEnd:this.endoftime, | |||
houseId:this.houseId | |||
} | |||
} | |||
this.$u.post("/matchKeywords/findKeywords", parames).then(data => { | |||
data.forEach(item=>{ | |||
if(item.isInterval==0){ | |||
item.name=item.name+item.unit+'-'+item.endName+item.unit | |||
} | |||
if(item.keywordsId==this.keywordIds){ | |||
item.checked=true | |||
}else{ | |||
item.checked=false | |||
} | |||
}) | |||
this.semanticlist=data; | |||
this.getinit(); | |||
}) | |||
}, | |||
//遮罩取消 | |||
allcancel(){ | |||
this.screeningshow1=false; | |||
this.screeningshow2=false; | |||
this.screeningshow3=false; | |||
this.screeningshow4=false; | |||
}, | |||
//自定义时间确认 | |||
totalTimeChange(e){ | |||
this.Datesicing=e.startDate+'至'+e.endDate; | |||
this.starttime=e.startDate; | |||
this.endoftime=e.endDate; | |||
this.activetime=this.Inthemiddletime; | |||
this.totalTimeShow=false; | |||
this.tadelist=[] | |||
this.allcancel() | |||
this.Accesstolevel() | |||
}, | |||
//时间选择 | |||
activetimetab(index){ | |||
if(index==5){ | |||
this.Inthemiddletime=index; | |||
this.totalTimeShow=!this.totalTimeShow; | |||
}else{ | |||
this.Datesicing=''; | |||
this.activetime=index; | |||
this.tadelist=[] | |||
this.allcancel() | |||
this.Accesstolevel() | |||
} | |||
}, | |||
//筛选弹框 | |||
clickscreening(i){ | |||
if(i==1){ | |||
this.screeningshow1=!this.screeningshow1; | |||
this.screeningshow2=false; | |||
this.screeningshow3=false; | |||
this.screeningshow4=false; | |||
}else if(i==2){ | |||
this.screeningshow2=!this.screeningshow2; | |||
this.screeningshow1=false; | |||
this.screeningshow3=false; | |||
this.screeningshow4=false; | |||
}else if(i==3){ | |||
this.screeningshow3=!this.screeningshow3; | |||
this.screeningshow2=false; | |||
this.screeningshow1=false; | |||
this.screeningshow4=false; | |||
}else{ | |||
this.screeningshow4=!this.screeningshow4; | |||
this.screeningshow2=false; | |||
this.screeningshow3=false; | |||
this.screeningshow1=false; | |||
} | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.timeactive111{ | |||
color: #2671E2; | |||
} | |||
*{ | |||
margin:0; | |||
padding:0; | |||
box-sizing:border-box; | |||
} | |||
.cenbox{ | |||
width: 100%; | |||
height: 100%; | |||
background-color: #F8F8F8; | |||
display:flex; | |||
flex-direction:column; | |||
.screeningtop{ | |||
width: 100%; | |||
height: 75rpx; | |||
background-color: #FFFFFF; | |||
border-bottom: 1px solid #E0E0E0; | |||
align-items: center; | |||
display: flex; | |||
align-items: center; | |||
position: relative; | |||
} | |||
.screeningview{ | |||
flex: 1; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
border-right: 1px solid #E0E0E0; | |||
} | |||
.zhuti{ | |||
flex:1; | |||
// soverflow:auto; | |||
} | |||
} | |||
.viewimg{ | |||
width: 20rpx; | |||
height: 100%; | |||
line-height: 72rpx; | |||
margin-left: 10rpx; | |||
image{ | |||
width: 20rpx; | |||
height: 12rpx; | |||
} | |||
} | |||
.cenforview{ | |||
width: 100%; | |||
height: 275rpx; | |||
background: #FFFFFF; | |||
margin-top: 20rpx; | |||
.cenfortop{ | |||
width: 100%; | |||
height: 146rpx; | |||
display: flex; | |||
// border-bottom: 1px solid #E0E0E0; | |||
.fortopzuo{ | |||
width: 16%; | |||
padding-top: 30rpx; | |||
.topzuoimg{ | |||
width: 60rpx; | |||
height: 60rpx; | |||
margin-left: 30rpx; | |||
border-radius: 50%; | |||
image{ | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
} | |||
.fortopyou{ | |||
width: 84%; | |||
height: 146rpx; | |||
.topyouview1{ | |||
width: 100%; | |||
margin-top: 28rpx; | |||
display: flex; | |||
.youview1-1{ | |||
width: 25%; | |||
font-size: 28rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
overflow: hidden; | |||
white-space:nowrap; | |||
text-overflow:ellipsis; | |||
} | |||
.youview1-2{ | |||
width: 75%; | |||
font-size: 26rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
} | |||
} | |||
.topyouview2{ | |||
width: 100%; | |||
font-size: 28rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
margin-top: 20rpx; | |||
} | |||
} | |||
} | |||
.cenforbottom{ | |||
width: 100%; | |||
height: 128rpx; | |||
display: flex; | |||
align-items: center; | |||
.forbottomview{ | |||
flex: 1; | |||
height: 128rpx; | |||
// border-right: 1px solid #E0E0E0; | |||
.bottomview1{ | |||
width: 100%; | |||
height: 26rpx; | |||
font-size: 26rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
line-height: 26rpx; | |||
text-align: center; | |||
margin-top: 24rpx; | |||
} | |||
.bottomview2{ | |||
width: 100%; | |||
height: 30rpx; | |||
font-size: 30rpx; | |||
font-weight: 600; | |||
color: #333333; | |||
line-height: 30rpx; | |||
text-align: center; | |||
margin-top: 24rpx; | |||
} | |||
} | |||
} | |||
} | |||
.timepick{ | |||
width: 100%; | |||
height: 210rpx; | |||
background: #FFFFFF; | |||
position: absolute; | |||
top: 74rpx; | |||
left: 0; | |||
z-index: 20; | |||
.tiempickbox{ | |||
width: 94%; | |||
margin: 0 auto; | |||
height: 56rpx; | |||
display: flex; | |||
align-items: center; | |||
margin-top: 25rpx; | |||
} | |||
.tiempickbox>view:nth-of-type(1){ | |||
width: 156rpx; | |||
height: 56rpx; | |||
border-radius: 4rpx; | |||
text-align: center; | |||
line-height: 56rpx; | |||
font-size: 28rpx; | |||
border: 1px solid #C9C9C9; | |||
} | |||
.tiempickbox>view:nth-of-type(2){ | |||
width: 156rpx; | |||
height: 56rpx; | |||
border-radius: 4rpx; | |||
text-align: center; | |||
line-height: 56rpx; | |||
font-size: 28rpx; | |||
border: 1px solid #C9C9C9; | |||
margin-left: 28rpx; | |||
} | |||
.tiempickbox>view:nth-of-type(3){ | |||
width: 156rpx; | |||
height: 56rpx; | |||
border-radius: 4rpx; | |||
text-align: center; | |||
line-height: 56rpx; | |||
font-size: 28rpx; | |||
border: 1px solid #C9C9C9; | |||
margin-left: 28rpx; | |||
} | |||
.tiempickbox>view:nth-of-type(4){ | |||
width: 156rpx; | |||
height: 56rpx; | |||
border-radius: 4rpx; | |||
text-align: center; | |||
line-height: 56rpx; | |||
font-size: 28rpx; | |||
border: 1px solid #C9C9C9; | |||
margin-left: 28rpx; | |||
} | |||
.tiempickzidingyi{ | |||
width: 94%; | |||
margin: 0 auto; | |||
margin-top: 28rpx; | |||
height: 60rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #C9C9C9; | |||
text-align: center; | |||
line-height: 60rpx; | |||
color: #666666; | |||
} | |||
} | |||
.call_zhezhao { | |||
position: fixed; | |||
width: 100%; | |||
height: 100%; | |||
top: 75rpx; | |||
left: 0rpx; | |||
opacity: 0.5; | |||
background-color: #666666; | |||
z-index: 10; | |||
} | |||
.timeactive{ | |||
color: #FFFFFF; | |||
background-color: #2671E2; | |||
} | |||
.userinput{ | |||
width: 100%; | |||
height: 126rpx; | |||
background: #FFFFFF; | |||
position: absolute; | |||
top: 74rpx; | |||
left: 0; | |||
z-index: 20; | |||
.inputdlex{ | |||
width: 90%; | |||
margin: 0 auto; | |||
height: 56rpx; | |||
display: flex; | |||
align-items: center; | |||
margin-top: 30rpx; | |||
.flexzuo{ | |||
width: 80%; | |||
.flexinput{ | |||
width: 96%; | |||
height: 100%; | |||
border-radius: 20rpx; | |||
border: 1px solid #C9C9C9; | |||
padding-left: 20rpx; | |||
font-size: 24rpx; | |||
} | |||
} | |||
.flexyou{ | |||
width: 20%; | |||
font-size: 28rpx; | |||
color: #2671E2; | |||
text-indent: 28rpx; | |||
} | |||
} | |||
} | |||
.yuyipick{ | |||
width: 100%; | |||
min-height: 300rpx; | |||
max-height: 500rpx; | |||
background: #FFFFFF; | |||
overflow-y: auto; | |||
// padding-bottom: 20rpx; | |||
position: absolute; | |||
top: 74rpx; | |||
left: 0; | |||
z-index: 20; | |||
.inputdlex{ | |||
width: 90%; | |||
margin: 0 auto; | |||
display: flex; | |||
flex-wrap: wrap; | |||
margin-top: 30rpx; | |||
} | |||
.inputdlex view{ | |||
width: 50%; | |||
font-size: 26rpx; | |||
font-weight: 400; | |||
text-align: center; | |||
margin-top: 26rpx; | |||
} | |||
} | |||
.screen-foot{ | |||
width: 100%; | |||
height: 88rpx; | |||
display: flex; | |||
margin-top: 20rpx; | |||
border-top: 1px solid #E0E0E0; | |||
.screen-foot-reset{ | |||
width: 50%; | |||
text-align: center; | |||
height: 88rpx; | |||
line-height: 88rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
} | |||
.screen-foot-sure{ | |||
width: 50%; | |||
text-align: center; | |||
line-height: 88rpx; | |||
height: 88rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #FFFFFF; | |||
background: #2671E2; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,405 @@ | |||
<template> | |||
<view class="box"> | |||
<view class="boxtittab"> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 4 }" @click="tabtimetap(4)">近七天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 5 }" @click="tabtimetap(5)">近15天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 6 }" @click="tabtimetap(6)">近30天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 3 }" @click="tabtimetap(3)">自定义</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">接待量排名(TOP10)</view> | |||
</view> | |||
<view class="hejisan"> | |||
<view class="sanbox1" style="width: 35%;"> | |||
<view class="text1-1">合计</view> | |||
<view class="text1-2">{{newlisttabinfo1.total}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 40%;"> | |||
<view class="text1-1">顾问</view> | |||
<view class="text1-2">{{newlisttabinfo1.count}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 25%;"> | |||
<view class="text1-1">人均接待量</view> | |||
<view class="text1-2">{{newlisttabinfo1.avg}}</view> | |||
</view> | |||
</view> | |||
<view class="jindu" style="height: 360rpx;overflow: auto;"> | |||
<view v-if="newlisttabinfo1.result.length!=0" class="jindu-box" v-for="(item,index) in newlisttabinfo1.result" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name" v-if="item.name">{{item.name.substring(0,4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#FBA448" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}</view> | |||
</view> | |||
</view> | |||
<view v-if="newlisttabinfo1.result.length==0" style="width: 100%;text-align: center;margin-top: 60rpx;"> | |||
暂无数据 | |||
</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">销讲执行率排行(TOP10)</view> | |||
</view> | |||
<view class="hejisan"> | |||
<view class="sanbox1" style="width: 40%;"> | |||
<view class="text1-1">顾问</view> | |||
<view class="text1-2">{{newlisttabinfo3.count}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 25%;"> | |||
<view class="text1-1">人均执行率</view> | |||
<view class="text1-2">{{newlisttabinfo3.avg}}</view> | |||
</view> | |||
</view> | |||
<view class="jindu" style="height: 360rpx;overflow: auto;"> | |||
<view v-if="newlisttabinfo3.result.length!=0" class="jindu-box" v-for="(item,index) in newlisttabinfo3.result" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name" v-if="item.name">{{item.name.substring(0,4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#FBA448" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}</view> | |||
</view> | |||
</view> | |||
<view v-if="newlisttabinfo3.result.length==0" style="width: 100%;text-align: center;margin-top: 60rpx;"> | |||
暂无数据 | |||
</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">录音时长(TOP10)</view> | |||
</view> | |||
<view class="hejisan"> | |||
<view class="sanbox1" style="width: 35%;"> | |||
<view class="text1-1">合计</view> | |||
<view class="text1-2">{{newlisttabinfo2.total}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 40%;"> | |||
<view class="text1-1">顾问</view> | |||
<view class="text1-2">{{newlisttabinfo2.count}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 25%;"> | |||
<view class="text1-1">人均录音时长</view> | |||
<view class="text1-2">{{newlisttabinfo2.avg}}</view> | |||
</view> | |||
</view> | |||
<view class="jindu" style="height: 360rpx;overflow: auto;"> | |||
<view v-if="newlisttabinfo2.result.length!=0" class="jindu-box" v-for="(item,index) in newlisttabinfo2.result" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name" v-if="item.name">{{item.name.substring(0,4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#FBA448" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}</view> | |||
</view> | |||
</view> | |||
<view v-if="newlisttabinfo2.result.length==0" style="width: 100%;text-align: center;margin-top: 60rpx;"> | |||
暂无数据 | |||
</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">违禁次数排名(TOP10)</view> | |||
</view> | |||
<view class="hejisan"> | |||
<view class="sanbox1" style="width: 35%;"> | |||
<view class="text1-1">合计</view> | |||
<view class="text1-2">{{newlisttabinfo4.total}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 40%;"> | |||
<view class="text1-1">顾问</view> | |||
<view class="text1-2">{{newlisttabinfo4.count}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 25%;"> | |||
<view class="text1-1">人均违禁次数</view> | |||
<view class="text1-2">{{newlisttabinfo4.avg}}</view> | |||
</view> | |||
</view> | |||
<view class="jindu" style="height: 360rpx;overflow: auto;"> | |||
<view v-if="newlisttabinfo4.result.length!=0" class="jindu-box" v-for="(item,index) in newlisttabinfo4.result" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name" v-if="item.name">{{item.name.substring(0,4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#FBA448" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}</view> | |||
</view> | |||
</view> | |||
<view v-if="newlisttabinfo4.result.length==0" style="width: 100%;text-align: center;margin-top: 60rpx;"> | |||
暂无数据 | |||
</view> | |||
</view> | |||
</view> | |||
<view v-if="false" style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single" v-if="false"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">接待未标顾问(TOP10)</view> | |||
</view> | |||
<view class="hejisan"> | |||
<view class="sanbox1" style="width: 35%;"> | |||
<view class="text1-1">合计</view> | |||
<view class="text1-2">{{newlisttabinfo4.total}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 40%;"> | |||
<view class="text1-1">顾问</view> | |||
<view class="text1-2">{{newlisttabinfo4.count}}</view> | |||
</view> | |||
<view class="sanbox1" style="width: 25%;"> | |||
<view class="text1-1">人均违禁次数</view> | |||
<view class="text1-2">{{newlisttabinfo4.avg}}</view> | |||
</view> | |||
</view> | |||
<view class="jindu" style="height: 360rpx;overflow: auto;"> | |||
<view v-if="newlisttabinfo4.result.length!=0" class="jindu-box" v-for="(item,index) in newlisttabinfo4.result" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name" v-if="item.name">{{item.name.substring(0,4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#FBA448" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}</view> | |||
</view> | |||
</view> | |||
<view v-if="newlisttabinfo4.result.length==0" style="width: 100%;text-align: center;margin-top: 60rpx;"> | |||
暂无数据 | |||
</view> | |||
</view> | |||
</view> | |||
<u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> | |||
</view> | |||
</template> | |||
<script> | |||
var app = getApp(); | |||
var util = require("../../../utils/util.js"); | |||
var config = require("../../../config"); | |||
export default { | |||
data() { | |||
return { | |||
activeTotal: 4, | |||
totalTimeShow: false, | |||
// 项目id | |||
houseId:'', | |||
lastEndDate:'', | |||
lastStartDate:'', | |||
newlisttabinfo1:{ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
}, | |||
newlisttabinfo2:{ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
}, | |||
newlisttabinfo3:{ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
}, | |||
newlisttabinfo4:{ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
}, | |||
}; | |||
}, | |||
onLoad() { | |||
// 获取项目id | |||
this.houseId = uni.getStorageSync('buildingID').id; | |||
this.init() | |||
}, | |||
onPullDownRefresh() { | |||
this.init() | |||
setTimeout(function () { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
methods: { | |||
init(){ | |||
this.newlisttabinfo1={ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
}, | |||
this.newlisttabinfo2={ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
}, | |||
this.newlisttabinfo3={ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
}, | |||
this.newlisttabinfo4={ | |||
avg:'', | |||
count:'', | |||
total:'', | |||
result:[], | |||
} | |||
var activeTotal=0; | |||
if(this.activeTotal==3){ | |||
activeTotal=null; | |||
}else{ | |||
activeTotal=this.activeTotal; | |||
this.lastEndDate=''; | |||
this.lastStartDate=''; | |||
} | |||
var promse={ | |||
timeType:activeTotal, | |||
lastStartDate:this.lastStartDate, | |||
lastEndDate:this.lastEndDate, | |||
houseId:this.houseId | |||
} | |||
this.staffStatisticsReceptionTop10(promse) | |||
this.staffStatisticsRecordingTimTop10(promse) | |||
this.staffStatisticsExecutionRateTop10(promse) | |||
this.staffStatisticsProhibitedTop10(promse) | |||
}, | |||
//接待量排名 | |||
staffStatisticsReceptionTop10(promse){ | |||
this.$u.post('/cusLvStatistics/staffStatisticsReceptionTop10',promse).then(res=>{ | |||
res.result.forEach(item=>{ | |||
item.zxl=item.data | |||
item.name=item.accountName | |||
}) | |||
res.result=this.dealData(res.result) | |||
this.newlisttabinfo1=res; | |||
}) | |||
}, | |||
//录音时长 | |||
staffStatisticsRecordingTimTop10(promse){ | |||
this.$u.post('/cusLvStatistics/staffStatisticsRecordingTimTop10',promse).then(res=>{ | |||
res.result.forEach(item=>{ | |||
item.zxl=item.data | |||
item.name=item.accountName | |||
}) | |||
res.result=this.dealData(res.result) | |||
this.newlisttabinfo2=res; | |||
}) | |||
}, | |||
//销讲 | |||
staffStatisticsExecutionRateTop10(promse){ | |||
this.$u.post('/cusLvStatistics/staffStatisticsExecutionRateTop10',promse).then(res=>{ | |||
res.result.forEach(item=>{ | |||
item.zxl=item.data; | |||
item.zxl1=item.data; | |||
item.name=item.accountName | |||
}) | |||
this.newlisttabinfo3=res; | |||
}) | |||
}, | |||
//j禁忌 | |||
staffStatisticsProhibitedTop10(promse){ | |||
this.$u.post('/cusLvStatistics/staffStatisticsProhibitedTop10',promse).then(res=>{ | |||
res.result.forEach(item=>{ | |||
item.zxl=item.data | |||
item.name=item.accountName | |||
}) | |||
res.result=this.dealData(res.result) | |||
this.newlisttabinfo4=res; | |||
}) | |||
}, | |||
//自定义时间 | |||
totalTimeChange(e) { | |||
console.log(e.startDate, e.endDate) | |||
this.activeTotal=3; | |||
this.lastEndDate=e.endDate | |||
this.lastStartDate=e.startDate | |||
this.init() | |||
}, | |||
//时间切换 | |||
tabtimetap(index) { | |||
if (index == 3) { | |||
this.totalTimeShow = true; | |||
} else { | |||
this.activeTotal = index; | |||
this.lastEndDate=''; | |||
this.lastStartDate=''; | |||
this.init() | |||
} | |||
}, | |||
// 定义一个公共方法对数据进行处理 | |||
dealData(arr){ | |||
// 获取最大值 | |||
let num=Math.max.apply(Math, arr.map(function (o) { return o.zxl })) //结果:3 | |||
// console.log(num) | |||
// if(num>100){ | |||
// // 获取最大值的下标 | |||
// // let idx=arr.findIndex(item=>item.zxl==num) | |||
// // console.log(idx,123) | |||
// arr.map(item=>{ | |||
// item.zxl1=Math.floor(item.zxl/num*100) | |||
// }) | |||
// // console.log(arr) | |||
// return arr | |||
// }else{ | |||
// arr.map(item=>{ | |||
// item.zxl1=item.zxl | |||
// }) | |||
// return arr | |||
// } | |||
arr.map(item=>{ | |||
item.zxl1=Math.floor(item.zxl/num*100) | |||
}) | |||
return arr | |||
}, | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100%; | |||
height: 100%; | |||
background: #FAFAFA; | |||
padding-bottom: 60rpx; | |||
} | |||
.hejisan{ | |||
width: 92%; | |||
margin: 0 auto; | |||
display: flex; | |||
padding-top: 20rpx; | |||
padding-bottom:20rpx; | |||
.text1-1{ | |||
color: #666666; | |||
} | |||
.text1-2{ | |||
color: #333333; | |||
margin-top: 10rpx; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,495 @@ | |||
<template> | |||
<view class="box"> | |||
<view class="boxtittab"> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 4 }" @click="tabtimetap(4)">近七天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 5 }" @click="tabtimetap(5)">近15天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 6 }" @click="tabtimetap(6)">近30天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 3 }" @click="tabtimetap(3)">自定义</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1">接待量(TOP10)</view> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">项目:{{newTeam1||0}}</view> | |||
<view class="heji">均值:{{newAvg1||0}}</view> | |||
</view> | |||
<view class="jindu"> | |||
<scroll-view style="height: 300rpx;" scroll-y="true" > | |||
<view class="jindu-box" v-for="(item,index) in newlisttabinfo1" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name">{{item.name.substring(0, 4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#FBA448" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1">接待时长(TOP10)</view> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">项目:{{newTeam2||0}}</view> | |||
<view class="heji">均值:{{newAvg2||0}}</view> | |||
</view> | |||
<view class="jindu"> | |||
<scroll-view style="height: 300rpx;" scroll-y="true" > | |||
<view class="jindu-box" v-for="(item,index) in newlisttabinfo2" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name">{{item.name.substring(0, 4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#4FC78F" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">销讲执行排名(TOP10)</view> | |||
<!-- <view class="title3" style="flex: 1;"> | |||
<view class="title3-box"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 0 }">执行率</view> | |||
</view> | |||
<view class="title3-box"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 1 }">得分</view> | |||
</view> | |||
</view> --> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">项目:{{newTeam3||0}}</view> | |||
<view class="heji">均值:{{newAvg3||0}}%</view> | |||
</view> | |||
<view class="jindu"> | |||
<scroll-view style="height: 300rpx;" scroll-y="true" > | |||
<view class="jindu-box" v-for="(item,index) in newlisttabinfo3" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name">{{item.name.substring(0, 4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#9B6BDF" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}%</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">顾问执行排名(TOP10)</view> | |||
<!-- <view class="title3" style="flex: 1;"> | |||
<view class="title3-box"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 0 }">执行率</view> | |||
</view> | |||
<view class="title3-box"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 1 }">得分</view> | |||
</view> | |||
</view> --> | |||
</view> | |||
<!-- <view class="hejibox"> | |||
<view class="heji">项目:{{newTeam4||0}}</view> | |||
<view class="heji">均值:{{newAvg4||0}}</view> | |||
</view> --> | |||
<view class="jindu"> | |||
<scroll-view style="height: 300rpx;" scroll-y="true" > | |||
<view class="jindu-box" v-for="(item,index) in newlisttabinfo4" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name">{{item.name.substring(0, 4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#9B6BDF" :percent="item.zxl1"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}%</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title" style="padding-right: 30rpx;"> | |||
<view class="title1" style="flex: 1;">销讲能力</view> | |||
<!-- <view class="title2" style="flex: 1;justify-content: flex-end;" @click="Groupcontrast"> | |||
<view class="title2-che">项目 | |||
<image class="righttochoose" src="../../../static/images/righttochoose.png" mode=""></image> | |||
</view> | |||
</view> --> | |||
<view class="title2" style="flex: 1;justify-content: flex-end;" @click="staffShow=true"> | |||
<view class="title2-che" style="width: auto;"><text style="margin-right: 40rpx;">{{staff.label}}</text> | |||
<image class="righttochoose" src="../../../static/images/righttochoose.png" mode=""></image> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- <view class="hejibox"> | |||
<view class="heji">项目:50</view> | |||
<view class="heji">均值:25</view> | |||
</view> --> | |||
<view class="uchaserbox"> | |||
<qiun-data-charts | |||
type="radar" | |||
:opts="opts" | |||
:chartData="chartData" | |||
:canvas2d="true" | |||
canvasId="wangxiaohuaerlingeryilingwuyib88" | |||
background="none" | |||
/> | |||
</view> | |||
</view> | |||
<!-- <view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1">禁忌执行率(TOP10)</view> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">合计:50</view> | |||
<view class="heji">均值:25</view> | |||
</view> | |||
<view class="jindu"> | |||
<view class="jindu-box" v-for="(item,index) in newlisttabinfo" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name">{{item.name.substring(0, 4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#E6625B" :percent="item.zxl"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}%</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> --> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<!-- <view class="single"> | |||
<view class="title" style="padding-right: 30rpx;"> | |||
<view class="title1" style="flex: 1;">违禁能力(TOP10)</view> | |||
<view class="title2" style="flex: 1;justify-content: flex-end;"> | |||
<view class="title2-che">项目 | |||
<image class="righttochoose" src="../../../static/images/righttochoose.png" mode=""></image> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">合计:50</view> | |||
<view class="heji">均值:25</view> | |||
</view> | |||
<view class="uchaserbox"> | |||
<qiun-data-charts | |||
type="radar" | |||
:chartData="chartData" | |||
:canvas2d="true" | |||
canvasId="wangxiaohuaerlingeryilingwuyib89" | |||
background="none" | |||
/> | |||
</view> | |||
</view> --> | |||
<u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> | |||
<!-- 选择项目 --> | |||
<u-select v-model="staffShow" :list="staffList" @confirm="staffSelectCallback" :default-value='selindex'></u-select> | |||
</view> | |||
</template> | |||
<script> | |||
var app = getApp(); | |||
var util = require("../../../utils/util.js"); | |||
var config = require("../../../config"); | |||
export default { | |||
data() { | |||
return { | |||
activeTotal: 4, | |||
activeTotal2: 0, | |||
bocindex:0, | |||
totalTimeShow: false, | |||
// 项目id | |||
houseId:'', | |||
staffShow:false, | |||
staffList:[], | |||
lastStartDate:'', | |||
lastEndDate :'', | |||
newTeam1:'', | |||
newAvg1:'', | |||
newTeam2:'', | |||
newAvg2:'', | |||
newTeam3:'', | |||
newAvg3:'', | |||
newTeam4:'', | |||
newAvg4:'', | |||
staff:{ | |||
value:'', | |||
label:'' | |||
}, | |||
newlisttabinfo1:[ | |||
{name:'接待量',zxl:'10'}, | |||
{name:'平均执行率',zxl:'50'}, | |||
{name:'接待客户',zxl:'80'}, | |||
], | |||
newlisttabinfo2:[ | |||
{name:'接待量',zxl:'10'}, | |||
{name:'平均执行率',zxl:'50'}, | |||
{name:'接待客户',zxl:'80'}, | |||
], | |||
newlisttabinfo3:[ | |||
{name:'接待量',zxl:'10'}, | |||
{name:'平均执行率',zxl:'50'}, | |||
{name:'接待客户',zxl:'80'}, | |||
], | |||
newlisttabinfo4:[ | |||
{name:'接待量',zxl:'10'}, | |||
{name:'平均执行率',zxl:'50'}, | |||
{name:'接待客户',zxl:'80'}, | |||
], | |||
chartData:{ | |||
"categories": ["维度1","维度2","维度3","维度4","维度5","维度6"], | |||
"series": [ | |||
{ | |||
"name": "成交量", | |||
"data": [90,110,165,195,187,172] | |||
} | |||
] | |||
}, | |||
opts: { | |||
fontSize: 10, | |||
extra: { | |||
radar: { | |||
max: '' | |||
} | |||
} | |||
} | |||
}; | |||
}, | |||
onLoad() { | |||
let that=this | |||
uni.$on('updateGroup',function(data){ | |||
console.log(data) | |||
that.houseId=data.arr.join(',') | |||
// 获取销奖能力 | |||
that.getPowerList() | |||
}) | |||
this.getSectionList() | |||
}, | |||
onPullDownRefresh(){ | |||
let that=this | |||
uni.$on('updateGroup',function(data){ | |||
console.log(data) | |||
that.houseId=data.arr.join(',') | |||
// 获取销奖能力 | |||
that.getPowerList() | |||
}) | |||
this.getSectionList() | |||
setTimeout(function () { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
methods: { | |||
// 获取部门列表 | |||
getSectionList(){ | |||
this.$u.post('/user/getHouseByToken',) | |||
.then(res=>{ | |||
// console.log(res) | |||
this.staffList=[] | |||
res.map((item,index)=>{ | |||
let obj={} | |||
obj.value=item.id | |||
obj.label=item.propertyName | |||
this.staffList.push(obj) | |||
}) | |||
this.houseId=this.staffList[0].value | |||
this.staff=this.staffList[0] | |||
this.getdata() | |||
// console.log(this.staffList,this.staffList,this.houseId) | |||
}) | |||
}, | |||
//指标执行率分析tab | |||
tapspagek2(index) { | |||
this.bocindex = index; | |||
}, | |||
staffSelectCallback(e){ | |||
this.staff=e[0] | |||
this.houseId=e[0].value | |||
this.getPowerList() | |||
}, | |||
getdata(){ | |||
// 请求接口获取接待量 | |||
this.receptionCountList('1','/cusLvStatistics/groupComparisonReception') | |||
// 接待时长 | |||
this.receptionCountList('2','/cusLvStatistics/groupComparisonReceptionTime') | |||
// 小将排名 | |||
this.receptionCountList('3','/cusLvStatistics/groupComparisonTalkRank') | |||
// 顾问牌名 | |||
this.receptionCountList('4','/cusLvStatistics/groupComparisonTalkRankByConsultant') | |||
// 销奖能力 | |||
this.getPowerList() | |||
}, | |||
//时间切换 | |||
tabtimetap(index) { | |||
if (index == 3) { | |||
this.totalTimeShow = true; | |||
} else { | |||
this.activeTotal = index; | |||
this.lastEndDate='' | |||
this.lastStartDate='' | |||
this.getdata() | |||
// // 获取数据 | |||
// // 团队对比接待量 | |||
// this.receptionCountList(0,1,'/cusLvStatistics/teamAnalysisReception') | |||
// // 团队对比接待时长 | |||
// this.receptionCountList(0,2,'/cusLvStatistics/teamAnalysisReceptionTime') | |||
// /* 销奖执行率 */ | |||
// this.receptionCountList(0,3,'/cusLvStatistics/teamAnalysisExecutionRate') | |||
// // 获取销奖能力 | |||
// this.getPowerList() | |||
} | |||
}, | |||
// 接待时长 | |||
receptionCountList(index,url){ | |||
this.$u.post(url,{ | |||
timeType:this.lastEndDate?null:this.activeTotal+'', | |||
lastEndDate:this.lastEndDate, | |||
lastStartDate:this.lastStartDate | |||
}) | |||
.then(res=>{ | |||
// console.log(res) | |||
let result=res.result | |||
this['newTeam'+index]=res.avg[0] | |||
this['newAvg'+index]=res.avg[1] | |||
// return | |||
// 处理数据 | |||
// 先处理牌名数据,需要进行判断全部还是单个 | |||
// 当为全部时 | |||
this['newlisttabinfo'+index]=[] | |||
// 当选择全部时 | |||
let arr=[] | |||
// 当两个都选择的时候 | |||
result.map(item=>{ | |||
let obj={} | |||
obj.name=item.houseName | |||
obj.zxl=item.data | |||
arr.push(obj) | |||
}) | |||
arr=this.dealData(arr) | |||
this['newlisttabinfo'+index]=arr | |||
}) | |||
}, | |||
// 获取销奖能力 | |||
getPowerList(){ | |||
this.$u.post('/cusLvStatistics/groupComparisonMarketingAbility',{ | |||
houseIds:this.houseId, | |||
timeType:this.lastEndDate?null:this.activeTotal+'', | |||
lastEndDate:this.lastEndDate, | |||
lastStartDate:this.lastStartDate | |||
}) | |||
.then(res=>{ | |||
// console.log(res,123) | |||
// 处理数据 | |||
// return | |||
this.chartData={ | |||
categories:[], | |||
series:[] | |||
} | |||
let allobj={ | |||
categories:[], | |||
series:[] | |||
} | |||
let max = 0; | |||
res.result.map((item,index)=>{ | |||
let obj={ | |||
name:item[0].houseName, | |||
data:[] | |||
} | |||
item.map(item1=>{ | |||
if(index==0){ | |||
allobj.categories.push(item1.name) | |||
} | |||
obj.data.push(item1.avgExecutionRate) | |||
if (max < item1.avgExecutionRate) max = item1.avgExecutionRate; | |||
}) | |||
allobj.series.push(obj) | |||
}) | |||
// console.log(allobj) | |||
this.opts.extra.radar.max = max + 25 | |||
this.chartData=allobj | |||
this.$forceUpdate() | |||
}) | |||
}, | |||
//自定义时间 | |||
totalTimeChange(e) { | |||
console.log(e.startDate, e.endDate) | |||
this.activeTotal=3; | |||
this.lastEndDate=e.endDate | |||
this.lastStartDate=e.startDate | |||
this.getdata() | |||
}, | |||
//集团对比 | |||
Groupcontrast(){ | |||
uni.navigateTo({ | |||
url: `/pages/center/Piabodata/selectGroup?ids=${this.houseId}` | |||
}); | |||
}, | |||
// 定义一个公共方法对数据进行处理 | |||
dealData(arr){ | |||
// 获取最大值 | |||
let num=Math.max.apply(Math, arr.map(function (o) { return o.zxl })) //结果:3 | |||
// console.log(num) | |||
if(num>100){ | |||
// 获取最大值的下标 | |||
// let idx=arr.findIndex(item=>item.zxl==num) | |||
// console.log(idx,123) | |||
arr.map(item=>{ | |||
item.zxl1=Math.floor(item.zxl/num*100) | |||
}) | |||
// console.log(arr) | |||
return arr | |||
}else{ | |||
arr.map(item=>{ | |||
item.zxl1=item.zxl | |||
}) | |||
return arr | |||
} | |||
}, | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100%; | |||
height: 100%; | |||
background: #FAFAFA; | |||
padding-bottom: 60rpx; | |||
} | |||
</style> |
@@ -0,0 +1,642 @@ | |||
<template> | |||
<view> | |||
<view class="boxtittab"> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 4 }" @click="tabtimetap(4)">近七天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 5 }" @click="tabtimetap(5)">近15天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 6 }" @click="tabtimetap(6)">近30天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 3 }" @click="tabtimetap(3)">自定义</view> | |||
</view> | |||
</view> | |||
<view class="timepick"> | |||
<view class="timepicktime" @click="chiocStaff(0)"> | |||
<view>{{staff1.label}}</view> | |||
<view> | |||
<image class="Underimg" src="../../../static/images/Underimg.png" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="timepickpick"> | |||
<view @click="checkboxChange()" style="width: 40rpx;height:40rpx;border: 1rpx solid #E0E0E0;"> | |||
<image v-if="timepickpickisshow" style="width: 40rpx;height: 40rpx;" src="../../../static/images/xuanzhong.png" mode=""></image> | |||
</view> | |||
<view style="font-size:26rpx;text-indent: 12rpx;">对比</view> | |||
</view> | |||
<view class="timepicktime" v-if="timepickpickisshow" @click="chiocStaff(1)"> | |||
<view>{{staff2.label}}</view> | |||
<view> | |||
<image class="Underimg" src="../../../static/images/Underimg.png" mode=""></image> | |||
</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">接待量</view> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">{{staff1.label}}:{{newTeam1||0}}</view> | |||
<view class="heji" v-if="timepickpickisshow">{{staff2.label}}:{{newAvg1||0}}</view> | |||
</view> | |||
<view class="danwei">来访(人)</view> | |||
<view class="uchaserbox"> | |||
<qiun-data-charts | |||
type="line" | |||
:chartData="lineOptsect" | |||
background="none" | |||
:ontouch="true" | |||
canvasId="wangxiaohuaerlingeryilingwuyibbb" | |||
:canvas2d="true" | |||
/> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">录音时长</view> | |||
<view class="title3" style="flex: 1;"> | |||
<!-- <view class="title3-box" style="width: 40%;" @click="tabtimetap1(0)"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 0 }">有效录音</view> | |||
</view> | |||
<view class="title3-box" style="width: 40%;"@click="tabtimetap1(1)"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 1 }">录音时长</view> | |||
</view> --> | |||
</view> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">{{staff1.label}}:{{newTeam2||0}}</view> | |||
<view class="heji" v-if="timepickpickisshow">{{staff2.label}}:{{newAvg2||0}}</view> | |||
</view> | |||
<view class="danwei">录音时长</view> | |||
<view class="uchaserbox"> | |||
<qiun-data-charts | |||
type="line" | |||
:chartData="lineOptsect1" | |||
background="none" | |||
:ontouch="true" | |||
canvasId="wangxiaouaerlingeryilingwuyibhh" | |||
:canvas2d="true" | |||
/> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1" style="flex: 1;">销讲执行率</view> | |||
<view class="title3" style="flex: 1;"> | |||
<!-- <view class="title3-box" style="width: 40%;" @click="tabtimetap1(0)"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 0 }">有效录音</view> | |||
</view> | |||
<view class="title3-box" style="width: 40%;"@click="tabtimetap1(1)"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 1 }">录音时长</view> | |||
</view> --> | |||
</view> | |||
</view> | |||
<view class="hejibox"> | |||
<view class="heji">{{staff1.label}}:{{newTeam3||0}}</view> | |||
<view class="heji" v-if="timepickpickisshow">{{staff2.label}}:{{newAvg3||0}}</view> | |||
</view> | |||
<!-- <view class="danwei">录音时长</view> --> | |||
<view class="uchaserbox"> | |||
<qiun-data-charts | |||
type="line" | |||
:chartData="lineOptsect2" | |||
background="none" | |||
:ontouch="true" | |||
canvasId="wangxiaohuaerlingryilingwuyibhh" | |||
:canvas2d="true" | |||
:opts="lineOpts" | |||
/> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title" style="padding-right: 30rpx;"> | |||
<view class="title1" style="flex: 1;">销讲能力</view> | |||
</view> | |||
<view class="uchaserbox" style="height: 70vh;"> | |||
<qiun-data-charts | |||
type="radar" | |||
:chartData="chartData" | |||
:canvas2d="true" | |||
canvasId="wangxiaohuaerlingeryilinwuycsdx" | |||
background="none" | |||
:opts="opts" | |||
/> | |||
</view> | |||
</view> | |||
<!-- <u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> --> | |||
<u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> | |||
<!-- 选择客户的选择框 --> | |||
<u-select v-model="staffShow" :list="staffList" @confirm="staffSelectCallback" :default-value='selindex'></u-select> | |||
<u-select v-model="staffShow1" :list="staffList1" @confirm="staffSelectCallback" :default-value='selindex'></u-select> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
timepickpickisshow:true, | |||
totalTimeShow: false, | |||
activeTotal:4, | |||
activeTotal2:1, | |||
// 项目id | |||
houseId:'', | |||
staffList:[], | |||
staffList1:[], | |||
staffShow:false, | |||
staffShow1:false, | |||
newTeam1:'', | |||
newAvg1:'', | |||
newTeam2:'', | |||
newAvg2:'', | |||
newTeam3:'', | |||
newAvg3:'', | |||
staff1:{ | |||
value:'', | |||
label:'' | |||
}, | |||
staff2:{ | |||
value:'', | |||
label:'平均' | |||
}, | |||
lineOpts: { | |||
yAxis: { | |||
data: [ | |||
{ | |||
max: 100, | |||
min: 0, | |||
} | |||
] | |||
} | |||
}, | |||
opts: { | |||
fontSize: 10, | |||
extra: { | |||
radar: { | |||
max: '' | |||
} | |||
} | |||
}, | |||
lastStartDate:'', | |||
lastEndDate :'', | |||
selindex:[0], | |||
choseStaffFlag:false, | |||
lineOptsect:{ | |||
"categories": ["2016","2017","2018","2019","2020","2021"], | |||
"series": [ | |||
{ | |||
"name": "成交量1", | |||
"data": [35,8,25,37,4,20] | |||
}, | |||
{ | |||
"name": "成交量2", | |||
"data": [40,18,45,44,10,60] | |||
} | |||
] | |||
}, | |||
lineOptsect1:{ | |||
"categories": ["2016","2017","2018","2019","2020","2021"], | |||
"series": [ | |||
{ | |||
"name": "成交量1", | |||
"data": [35,8,25,37,4,20] | |||
}, | |||
{ | |||
"name": "成交量2", | |||
"data": [40,18,45,44,10,60] | |||
} | |||
] | |||
}, | |||
lineOptsect2:{ | |||
"categories": ["2016","2017","2018","2019","2020","2021"], | |||
"series": [ | |||
{ | |||
"name": "成交量1", | |||
"data": [35,8,25,37,4,20] | |||
}, | |||
{ | |||
"name": "成交量2", | |||
"data": [40,18,45,44,10,60] | |||
} | |||
] | |||
}, | |||
chartData:{ | |||
"categories": ["维度1","维度2","维度3","维度4","维度5","维度6"], | |||
"series": [ | |||
{ | |||
"name": "成交量", | |||
"data": [90,110,165,195,187,172] | |||
} | |||
] | |||
} | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
// 获取项目id | |||
this.houseId = uni.getStorageSync('buildingID').id; | |||
// this.buildingname = uni.getStorageSync('buildingID').name; | |||
// 请求接口获取所有置业顾问员工的列表 | |||
this.getStaffList() | |||
}, | |||
onPullDownRefresh() { | |||
this.getStaffList() | |||
setTimeout(function () { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
methods: { | |||
//是否对比 | |||
checkboxChange(){ | |||
this.timepickpickisshow=!this.timepickpickisshow; | |||
this.staff2.value='' | |||
this.staff2.label='平均' | |||
// this.getreception() | |||
// this.getRecordList() | |||
// this.getAwardList() | |||
// this.getAward() | |||
this.getdata() | |||
}, | |||
// 点击员工对比 | |||
chiocStaff(idx){ | |||
if(idx==0){ | |||
// 当选择了第一个的时候 | |||
this.choseStaffFlag=false | |||
this.staffShow=true | |||
}else{ | |||
this.choseStaffFlag=true | |||
this.staffShow1=true | |||
} | |||
}, | |||
// 获取员工列表 | |||
getStaffList(){ | |||
this.$u.post('/cusLvStatistics/selectAllAccountIdByHouseId',{houseId:this.houseId}) | |||
.then(res=>{ | |||
// console.log(res,'123') | |||
this.staffList=[] | |||
this.staffList1=[] | |||
res.map(item=>{ | |||
let obj={} | |||
obj.value=item.accountId | |||
obj.label=item.name | |||
this.staffList.push(obj) | |||
}) | |||
this.staffList1=[...this.staffList] | |||
this.staffList1.unshift({ | |||
value:'', | |||
label:'平均' | |||
}) | |||
this.staff1=this.staffList[0] | |||
// this.getreception() | |||
// this.getRecordList() | |||
// this.getAwardList() | |||
// this.getAward() | |||
this.getdata() | |||
}) | |||
}, | |||
getdata(){ | |||
this.getreception() | |||
this.getRecordList() | |||
this.getAward() | |||
this.getAwardList() | |||
}, | |||
// 获取接待量数据 | |||
getreception(){ | |||
this.$u.post('/cusLvStatistics/employeeAnalysisReception',{ | |||
userA:this.staff1.value, | |||
userB:this.staff2.value, | |||
houseId:this.houseId, | |||
timeType:this.lastEndDate?null:this.activeTotal+'', | |||
lastEndDate:this.lastEndDate, | |||
lastStartDate:this.lastStartDate | |||
}) | |||
.then(res=>{ | |||
this.newTeam1=res.avg[0] | |||
this.newAvg1=res.avg[1] | |||
// console.log(res) | |||
let first=res.first | |||
let second=res.second | |||
this.lineOptsect.categories=[] | |||
if(!this.timepickpickisshow){ | |||
this.lineOptsect.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
} | |||
] | |||
first.map(item=>{ | |||
this.lineOptsect.categories.push(item.statDate.slice(5,10)) | |||
this.lineOptsect.series[0].data.push(item.receptionCount||0) | |||
}) | |||
}else{ | |||
this.lineOptsect.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
}, | |||
{ | |||
"name": second[0].accountName, | |||
"data": [] | |||
} | |||
] | |||
first.map(item=>{ | |||
this.lineOptsect.categories.push(item.statDate.slice(5,10)) | |||
this.lineOptsect.series[0].data.push(item.receptionCount) | |||
}) | |||
second.map(item=>{ | |||
this.lineOptsect.series[1].data.push(item.receptionCount) | |||
}) | |||
} | |||
// console.log(this.lineOptsect,'1') | |||
}) | |||
}, | |||
// 销奖趋势 | |||
getAward(){ | |||
this.$u.post('/cusLvStatistics/employeeAnalysisExacutiveRate',{ | |||
userA:this.staff1.value, | |||
userB:this.staff2.value, | |||
houseId:this.houseId, | |||
timeType:this.lastEndDate?null:this.activeTotal+'', | |||
lastEndDate:this.lastEndDate, | |||
lastStartDate:this.lastStartDate | |||
}) | |||
.then(res=>{ | |||
this.newTeam3=res.avg[0] | |||
this.newAvg3=res.avg[1] | |||
// console.log(res) | |||
let first=res.first | |||
let second=res.second | |||
this.lineOptsect2.categories=[] | |||
if(!this.timepickpickisshow){ | |||
this.lineOptsect2.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
} | |||
] | |||
first.map(item=>{ | |||
// console.log(item) | |||
this.lineOptsect2.categories.push(item.statDate.slice(5,10)) | |||
this.lineOptsect2.series[0].data.push(item.sumFraction) | |||
}) | |||
}else{ | |||
this.lineOptsect2.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
}, | |||
{ | |||
"name": second[0].accountName, | |||
"data": [] | |||
} | |||
] | |||
first.map(item=>{ | |||
this.lineOptsect2.categories.push(item.statDate.slice(5,10)) | |||
this.lineOptsect2.series[0].data.push(item.sumFraction) | |||
}) | |||
second.map(item=>{ | |||
this.lineOptsect2.series[1].data.push(item.sumFraction) | |||
}) | |||
} | |||
// console.log(this.lineOptsect2,'3') | |||
}) | |||
}, | |||
// 获取有效录音 | |||
async getRecordList(){ | |||
// 当选择有效录音时 | |||
let res=null | |||
if(this.activeTotal2==0){ | |||
res= await this.$u.post('/cusLvStatistics/employeeAnalysisEffectiveRecording',{ | |||
userA:this.staff1.value, | |||
userB:this.staff2.value, | |||
houseId:this.houseId, | |||
timeType:this.lastEndDate?null:this.activeTotal+'', | |||
lastEndDate:this.lastEndDate, | |||
lastStartDate:this.lastStartDate | |||
}) | |||
}else{ | |||
res= await this.$u.post('/cusLvStatistics/employeeAnalysisRecordingTime',{ | |||
userA:this.staff1.value, | |||
userB:this.staff2.value, | |||
houseId:this.houseId, | |||
timeType:this.lastEndDate?null:this.activeTotal+'', | |||
lastEndDate:this.lastEndDate, | |||
lastStartDate:this.lastStartDate | |||
}) | |||
} | |||
// console.log(res) | |||
this.newTeam2=res.avg[0] | |||
this.newAvg2=res.avg[1] | |||
let first=res.first | |||
let second=res.second | |||
this.lineOptsect1.categories=[] | |||
if(!this.timepickpickisshow){ | |||
this.lineOptsect1.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
} | |||
] | |||
first.map(item=>{ | |||
this.lineOptsect1.categories.push(item.statDate.slice(5,10)) | |||
this.lineOptsect1.series[0].data.push(item.sumDuration) | |||
}) | |||
}else{ | |||
this.lineOptsect1.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
}, | |||
{ | |||
"name": second[0].accountName, | |||
"data": [] | |||
} | |||
] | |||
first.map(item=>{ | |||
this.lineOptsect1.categories.push(item.statDate.slice(5,10)) | |||
this.lineOptsect1.series[0].data.push(item.sumDuration) | |||
}) | |||
second.map(item=>{ | |||
this.lineOptsect1.series[1].data.push(item.sumDuration) | |||
}) | |||
} | |||
// console.log(this.lineOptsect1,'2') | |||
}, | |||
// 获取销奖能力 | |||
getAwardList(){ | |||
this.$u.post('/cusLvStatistics/employeeAnalysisLevel1Fraction',{ | |||
userA:this.staff1.value, | |||
userB:this.staff2.value, | |||
houseId:this.houseId, | |||
timeType:this.lastEndDate?null:this.activeTotal+'', | |||
lastEndDate:this.lastEndDate, | |||
lastStartDate:this.lastStartDate | |||
}) | |||
.then(res=>{ | |||
// console.log(res) | |||
let first=res.first | |||
let second=res.second | |||
let max = first[0].avgExecutionRate | |||
this.chartData.categories=[] | |||
if(!this.timepickpickisshow){ | |||
this.chartData.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
} | |||
] | |||
first.map(item=>{ | |||
if (max < item.avgExecutionRate) max = item.avgExecutionRate; | |||
this.chartData.categories.push(item.name) | |||
this.chartData.series[0].data.push(item.avgExecutionRate) | |||
}) | |||
}else{ | |||
this.chartData.series=[ | |||
{ | |||
name:first[0].accountName, | |||
data:[] | |||
}, | |||
{ | |||
"name": second[0].accountName, | |||
"data": [] | |||
} | |||
] | |||
first.map(item=>{ | |||
this.chartData.categories.push(item.name) | |||
this.chartData.series[0].data.push(item.avgExecutionRate) | |||
}) | |||
second.map(item=>{ | |||
this.chartData.series[1].data.push(item.avgExecutionRate) | |||
}) | |||
let all = [...first, ...second] | |||
all.map(item => { | |||
if (max < item.avgExecutionRate) max = item.avgExecutionRate; | |||
}) | |||
} | |||
this.opts.extra.radar.max = max + 25 | |||
}) | |||
}, | |||
tabtimetap(index){ | |||
if (index == 3) { | |||
this.totalTimeShow = true; | |||
} else { | |||
this.activeTotal = index; | |||
this.lastEndDate='' | |||
this.lastStartDate='' | |||
// 获取数据 | |||
// this.getreception() | |||
// this.getRecordList() | |||
// this.getAwardList() | |||
this.getdata() | |||
} | |||
}, | |||
tabtimetap1(index){ | |||
this.activeTotal2 = index; | |||
// 调用方法 | |||
this.getRecordList() | |||
}, | |||
//自定义时间 | |||
totalTimeChange(e) { | |||
console.log(e.startDate, e.endDate) | |||
this.activeTotal=3; | |||
this.lastEndDate=e.endDate | |||
this.lastStartDate=e.startDate | |||
// 获取数据 | |||
// this.getreception() | |||
// this.getRecordList() | |||
// this.getAwardList() | |||
this.getdata() | |||
}, | |||
staffSelectCallback(e){ | |||
if(this.choseStaffFlag){ | |||
// 第二个客户 | |||
// console.log(e,'第二个') | |||
this.staff2=e[0] | |||
}else{ | |||
// 第一个客户 | |||
// console.log(e,'第一个') | |||
this.staff1=e[0] | |||
} | |||
if(this.staff1.label==this.staff2.label){ | |||
uni.showToast({ | |||
title:'请勿选择重复', | |||
icon:'none' | |||
}) | |||
this.staff2.label='请选择' | |||
// this.staff2.label='平均' | |||
// this.staff2.value='' | |||
return | |||
}else{ | |||
// 获取数据 | |||
// this.getreception() | |||
// this.getRecordList() | |||
// this.getAwardList() | |||
this.getdata() | |||
} | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
// 对比时间切换 | |||
.timepick{ | |||
width: 100%; | |||
height: 90rpx; | |||
display: flex; | |||
align-items: center; | |||
background: #FAFAFA; | |||
} | |||
.timepicktime{ | |||
width: 260rpx; | |||
height: 50rpx; | |||
border: 1rpx solid #E0E0E0; | |||
margin-left: 30rpx; | |||
display: flex; | |||
background: #FFFFFF; | |||
} | |||
.timepicktime>view:nth-of-type(1){ | |||
width: 210rpx; | |||
height: 100%; | |||
line-height: 50rpx; | |||
font-size: 26rpx; | |||
font-weight: 400; | |||
text-align: center; | |||
} | |||
.timepicktime>view:nth-of-type(2){ | |||
width: 49rpx; | |||
height: 100%; | |||
// border-left: 1px solid #E0E0E0; | |||
} | |||
.timepickpick{ | |||
width: 110rpx; | |||
height: 50rpx; | |||
margin-left: 30rpx; | |||
display: flex; | |||
align-items: center; | |||
} | |||
.Underimg{ | |||
width: 50rpx; | |||
height:50rpx; | |||
margin-top: -2rpx; | |||
} | |||
</style> |
@@ -0,0 +1,479 @@ | |||
<template> | |||
<view class="box"> | |||
<view class="boxtittab"> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 0 }" @click="tabtimetap(0)">今日</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 1 }" @click="tabtimetap(1)">昨日</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 2 }" @click="tabtimetap(2)">近一周</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 3 }" @click="tabtimetap(3)">自定义</view> | |||
</view> | |||
</view> | |||
<view class="boxzonglan"> | |||
<view class="zonglantit">客群特征总览</view> | |||
<view class="zonglanbox"> | |||
<view class="grid" v-for="(item,index) in numlist" :key="index" v-if="item.isshow"> | |||
<view class="audonum">{{item.name}}<text v-if="index!=0">触达次数</text></view> | |||
<view class="num">{{item.num}}</view> | |||
</view> | |||
</view> | |||
<view v-if="Afolding==true" class="anclack" @click="anclick(1)">展开 <u-icon style="margin-left: 8rpx;" label-color='#666666' name="arrow-down"></u-icon></view> | |||
<view v-if="Afolding==false" class="anclack" @click="anclick(2)">收起 <u-icon style="margin-left: 8rpx;" label-color='#666666' name="arrow-up"></u-icon></view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="centerfor" v-for="(item,index) in objlist" :key="index"> | |||
<view class="fortit"> | |||
<view class="left"> | |||
<view class="lefti"></view> | |||
<view class="lefttext">{{item.name}}触达排名</view> | |||
</view> | |||
<view class="right"> | |||
<view :class="{ activeclass: item.activeTab == 0 }" @click="charttoswitch(index,0)">表格</view> | |||
<view style="margin-left: 16rpx;" :class="{ activeclass: item.activeTab == 1 }" | |||
@click="charttoswitch(index,1)">饼状图</view> | |||
</view> | |||
</view> | |||
<view v-if="item.activeTab==0" class="tabdada"> | |||
<view class="tabth"> | |||
<view>排名</view> | |||
<view>画像语意词/触达客户</view> | |||
<view>触达占比</view> | |||
<view>沟通记录</view> | |||
</view> | |||
<view v-if="item.total==0" style="color: #999999;width: 100%;height: 500rpx;line-height: 500rpx;text-align: center;" >暂无数据</view> | |||
<view class="tabtd" v-if="item.total!=0" v-for="(chend,i) in item.matchKeywords" :key="i"> | |||
<view> | |||
<image v-if="i==0" class="ranking" src="../../../static/images/ranking1.png" mode=""></image> | |||
<image v-else-if="i==1" class="ranking" src="../../../static/images/ranking2.png" mode=""></image> | |||
<image v-else-if="i==2" class="ranking" src="../../../static/images/ranking3.png" mode=""></image> | |||
<view class="ranking1" v-else>{{i+1}}</view> | |||
</view> | |||
<view>{{chend.name}}({{chend.total}})</view> | |||
<view>{{chend.proportion}}%</view> | |||
<view @click="Toview(item,i)">查看</view> | |||
</view> | |||
</view> | |||
<view v-if="item.activeTab==1" class="tabech"> | |||
<qiun-data-charts | |||
:key="item.id" | |||
type="ring" | |||
:chartData="item.chartData" | |||
:canvas2d="true" | |||
:canvasId="'wangxiaohuahahahahaha'+item.id" | |||
:opts='item.opts' | |||
background="none" /> | |||
</view> | |||
</view> | |||
<u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> | |||
<u-back-top :scroll-top="scrollTop"></u-back-top> | |||
</view> | |||
</template> | |||
<script> | |||
var app = getApp(); | |||
var util = require("../../../utils/util.js"); | |||
var config = require("../../../config"); | |||
export default { | |||
data() { | |||
return { | |||
scrollTop: 0, | |||
activeTotal: 2, | |||
timeobj:{ | |||
statDateStart:'', | |||
statDateEnd:'' | |||
}, | |||
buildingID:'', | |||
totalTimeShow: false, | |||
activeTab: 0, | |||
numlist:[], | |||
objlist:[], | |||
Afolding:true | |||
}; | |||
}, | |||
onPageScroll(e) { | |||
this.scrollTop = e.scrollTop; | |||
}, | |||
onLoad() { | |||
this.buildingID=uni.getStorageSync('buildingID').id; | |||
this.gitinit() | |||
}, | |||
onPullDownRefresh() { | |||
this.gitinit() | |||
setTimeout(function () { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
methods: { | |||
anclick(i){ | |||
console.log(i) | |||
this.Afolding=!this.Afolding; | |||
this.numlist.forEach((citem,index)=>{ | |||
if(index<6){ | |||
citem.isshow=true; | |||
}else{ | |||
citem.isshow=!citem.isshow; | |||
} | |||
}) | |||
this.$forceUpdate() | |||
}, | |||
//获取数据 | |||
gitinit(){ | |||
this.objlist=[]; | |||
this.numlist=[]; | |||
var dateType=''; | |||
if(this.activeTotal==3){ | |||
dateType=null; | |||
}else{ | |||
dateType=this.activeTotal; | |||
} | |||
let parames={ | |||
dateType:dateType, | |||
statDateStart:this.timeobj.statDateStart, | |||
statDateEnd:this.timeobj.statDateEnd, | |||
houseId:this.buildingID | |||
} | |||
this.$u.post("/matchKeywords/findmatchdata", parames).then(data => { | |||
this.numlist.push({ | |||
name:"客户数量", | |||
num:data.total | |||
}) | |||
data.list.forEach((item,index)=>{ | |||
this.numlist.push({ | |||
name:item.name, | |||
num:item.total | |||
}) | |||
item.activeTab=0; | |||
item.opts={ | |||
"title": { | |||
"name": item.total, | |||
"color": '#666666', | |||
"fontSize": 20 | |||
}, | |||
"subtitle": { | |||
"name": '总触达次数', | |||
"color": '#32363D', | |||
"fontSize": 12, | |||
"offsetY": 4 | |||
} | |||
} | |||
item.chartData={ | |||
"categories": [], | |||
"series": [{ | |||
"data": [] | |||
}], | |||
}; | |||
item.matchKeywords.forEach(chend=>{ | |||
item.chartData.series[0].data.push({ | |||
"name":chend.name, | |||
"value": chend.proportion | |||
}) | |||
}) | |||
}) | |||
data.list.forEach(item=>{ | |||
item.matchKeywords.forEach(chend=>{ | |||
if(chend.isInterval==0){ | |||
chend.name=chend.name+chend.unit+'-'+chend.endName+chend.unit | |||
}else{ | |||
chend.name=chend.name | |||
} | |||
}) | |||
}) | |||
this.objlist=data.list; | |||
this.Afolding=true; | |||
this.numlist.forEach((citem,index)=>{ | |||
if(index<6){ | |||
citem.isshow=true | |||
}else{ | |||
citem.isshow=false | |||
} | |||
}) | |||
}) | |||
}, | |||
//查看 | |||
Toview(item,i){ | |||
console.log(item) | |||
let keywordsid = 0 | |||
if (item.matchKeywords[i].children && item.matchKeywords[i].children.length > 0) { | |||
keywordsid = item.matchKeywords[i].children[0].keywordsId | |||
} else { | |||
keywordsid = item.matchKeywords[i].keywordsId | |||
} | |||
uni.navigateTo({ | |||
url: '/pages/center/Piabodata/Customerportrait/Receivingrecords?datatype='+this.activeTotal+"&keywordsId="+keywordsid+"&starttime="+this.timeobj.statDateStart+"&endoftime="+this.timeobj.statDateEnd | |||
}) | |||
}, | |||
//时间切换 | |||
tabtimetap(index) { | |||
if (index == 3) { | |||
this.totalTimeShow = true; | |||
} else { | |||
this.activeTotal = index; | |||
this.gitinit() | |||
} | |||
}, | |||
//自定义时间 | |||
totalTimeChange(e) { | |||
this.timeobj.statDateStart = e.startDate; | |||
this.timeobj.statDateEnd = e.endDate; | |||
this.activeTotal=3; | |||
this.gitinit() | |||
}, | |||
charttoswitch(index,num) { | |||
this.objlist[index].activeTab=num | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.anclack{ | |||
width: 100%; | |||
height: 78rpx; | |||
text-align: center; | |||
line-height: 78rpx; | |||
font-size: 30rpx; | |||
border: 1rpx solid #E0E0E0; | |||
font-weight: 400; | |||
color: #666666; | |||
} | |||
.box { | |||
width: 100%; | |||
height: 100%; | |||
background: #FAFAFA; | |||
padding-bottom: 60rpx; | |||
} | |||
.boxtittab { | |||
width: 100; | |||
height: 92rpx; | |||
background: #FFFFFF; | |||
border: 1px solid #E0E0E0; | |||
display: flex; | |||
align-items: center; | |||
.tabbox { | |||
flex: 1; | |||
height: 100%; | |||
text-align: center; | |||
line-height: 92rpx; | |||
color: #666666; | |||
font-size: 28rpx; | |||
display: flex; | |||
justify-content: center; | |||
.activecllasscet { | |||
width: 96rpx; | |||
border-bottom: 2px solid #2671E2; | |||
} | |||
} | |||
} | |||
.tabtime { | |||
width: 100%; | |||
height: 50rpx; | |||
text-align: center; | |||
line-height: 50rpx; | |||
font-size: 24rpx; | |||
color: #666666; | |||
} | |||
.boxzonglan { | |||
width: 100%; | |||
min-height: 496rpx; | |||
background: #FFFFFF; | |||
padding: 30rpx 30rpx 30rpx 30rpx; | |||
.zonglantit { | |||
font-size: 30rpx; | |||
color: #333333; | |||
font-family: PingFangSC-Semibold, PingFang SC; | |||
font-weight: 600; | |||
} | |||
.zonglanbox { | |||
width: 100%; | |||
display: flex; | |||
flex-wrap: wrap; | |||
margin-top: 24rpx; | |||
.grid { | |||
width: 50%; | |||
height: 128rpx; | |||
border: 1px solid #E0E0E0; | |||
.audonum { | |||
color: #666666; | |||
text-indent: 40rpx; | |||
font-size: 26rpx; | |||
margin-top: 20rpx; | |||
} | |||
.num { | |||
color: #333333; | |||
text-indent: 40rpx; | |||
font-size: 32rpx; | |||
font-weight: 600; | |||
margin-top: 10rpx; | |||
} | |||
} | |||
} | |||
} | |||
.centerfor { | |||
width: 100%; | |||
height: 686rpx; | |||
background: #FFFFFF; | |||
padding-left: 30rpx; | |||
padding-right: 30rpx; | |||
margin-top: 20rpx; | |||
.fortit { | |||
width: 100%; | |||
height: 86rpx; | |||
display: flex; | |||
border-bottom: 1px solid #E0E0E0; | |||
.left { | |||
width: 70%; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
.lefti { | |||
width: 6rpx; | |||
height: 30rpx; | |||
background: #2671E2; | |||
} | |||
.lefttext { | |||
font-size: 30rpx; | |||
font-family: PingFangSC-Semibold, PingFang SC; | |||
font-weight: 600; | |||
color: #333333; | |||
margin-left: 10rpx; | |||
} | |||
} | |||
.right { | |||
width: 30%; | |||
height: 70rpx; | |||
display: flex; | |||
font-size: 28rpx; | |||
align-items: center; | |||
margin-top: 16rpx; | |||
} | |||
.right view { | |||
width: 92rpx; | |||
height: 50rpx; | |||
text-align: center; | |||
} | |||
} | |||
} | |||
.activeclass { | |||
color: #2671E2; | |||
border-bottom: 2px solid #2671E2; | |||
} | |||
.tabdada { | |||
width: 100%; | |||
height: 580rpx; | |||
overflow-y: auto; | |||
padding-bottom: 20rpx; | |||
} | |||
.tabth { | |||
width: 100%; | |||
height: 28rpx; | |||
display: flex; | |||
font-size: 28rpx; | |||
line-height: 28rpx; | |||
color: #666666; | |||
margin-top: 28rpx; | |||
} | |||
.tabth>view:nth-of-type(1) { | |||
width: 10%; | |||
text-align: center; | |||
} | |||
.tabth>view:nth-of-type(2) { | |||
width: 46%; | |||
text-align: center; | |||
} | |||
.tabth>view:nth-of-type(3) { | |||
width: 22%; | |||
text-align: center; | |||
} | |||
.tabth>view:nth-of-type(4) { | |||
width: 22%; | |||
text-align: center; | |||
} | |||
.tabtd { | |||
width: 100%; | |||
height: 30rpx; | |||
display: flex; | |||
font-size: 26rpx; | |||
line-height: 30rpx; | |||
margin-top: 32rpx; | |||
} | |||
.tabtd>view:nth-of-type(1) { | |||
width: 10%; | |||
text-align: center; | |||
line-height: 30rpx; | |||
} | |||
.tabtd>view:nth-of-type(2) { | |||
width: 46%; | |||
text-align: center; | |||
color: #333333; | |||
} | |||
.tabtd>view:nth-of-type(3) { | |||
width: 22%; | |||
text-align: center; | |||
color: #333333; | |||
} | |||
.tabtd>view:nth-of-type(4) { | |||
width: 22%; | |||
text-align: center; | |||
color: #2671E2; | |||
} | |||
.ranking { | |||
width: 34rpx; | |||
height: 34rpx; | |||
} | |||
.ranking1 { | |||
width: 30rpx; | |||
height: 30rpx; | |||
background: #ECF1FF; | |||
color: #424D64; | |||
font-size: 18rpx; | |||
text-align: center; | |||
line-height: 30rpx; | |||
border-radius: 50%; | |||
margin: 0 auto; | |||
} | |||
.tabech { | |||
width: 100%; | |||
height: 600rpx; | |||
} | |||
</style> |
@@ -0,0 +1,752 @@ | |||
<template> | |||
<view class="box"> | |||
<view class="boxtittab"> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 4 }" @click="tabtimetap(4)">近七天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 5 }" @click="tabtimetap(5)">近15天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 6 }" @click="tabtimetap(6)">近30天</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 3 }" @click="tabtimetap(3)">自定义</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="Piabodata-box"> | |||
<view class="Piabodata" @click="toTrendAnalysis()"> | |||
<view class="Piabodata-img"> | |||
<image class="Piabodata-img1" src="../../../static/images/qushi.png" mode=""></image> | |||
</view> | |||
<view class="Piabodata-text">趋势分析</view> | |||
</view> | |||
<view class="Piabodata" @click="toStaffAnalysis()"> | |||
<view class="Piabodata-img"> | |||
<image class="Piabodata-img1" src="../../../static/images/yuangong.png" mode=""></image> | |||
</view> | |||
<view class="Piabodata-text">员工分析</view> | |||
</view> | |||
<view class="Piabodata" @click="toUserinsightinto()"> | |||
<view class="Piabodata-img"> | |||
<image class="Piabodata-img1" src="../../../static/images/yinghu.png" mode=""></image> | |||
</view> | |||
<view class="Piabodata-text">用户洞察</view> | |||
</view> | |||
<view class="Piabodata" @click="Theteamcompared()" v-if="Theteamcomparedisshow"> | |||
<view class="Piabodata-img"> | |||
<image class="Piabodata-img1" src="../../../static/images/tuandui.png" mode=""></image> | |||
</view> | |||
<view class="Piabodata-text">团队对比</view> | |||
</view> | |||
<view class="Piabodata" @click="Groupcontrast()" v-if="Groupcontrastisshow"> | |||
<view class="Piabodata-img"> | |||
<image class="Piabodata-img1" src="../../../static/images/jituan.png" mode=""></image> | |||
</view> | |||
<view class="Piabodata-text">集团对比</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="boxzonglan" style="min-height: 400rpx;"> | |||
<view class="zonglantit">简报</view> | |||
<view class="zonglanbox"> | |||
<view class="grid" v-for="(item,index) in numlist" :key="index"> | |||
<view class="audonum">{{item.name}}</text></view> | |||
<view class="num">{{item.num}}</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1">接待趋势</view> | |||
</view> | |||
<view class="swiper-box"> | |||
<u-tabs-swiper ref="tabs" font-size="30" :bold="true" swiper-width="600" :current="bocindex" | |||
@change="tapspagek2()" inactive-color="#b1b1b1" active-color="#008ef2" :list="newlistoj1" | |||
:is-scroll="true"> | |||
</u-tabs-swiper> | |||
</view> | |||
<!-- <view class="hejibox"> | |||
<view class="heji">合计:50</view> | |||
<view class="heji">均值:25</view> | |||
</view> --> | |||
<view class="danwei">{{danwei}} </view> | |||
<view class="uchaserbox"> | |||
<template v-if="danwei == '单位(%)'"> | |||
<qiun-data-charts type="line" :chartData="lineOptsect" :opts="lineOpts" background="none" | |||
:ontouch="true" canvasId="wangxiaohuaerlingilingwuyiba1" :canvas2d="true" /> | |||
</template> | |||
<template v-else> | |||
<qiun-data-charts type="line" :chartData="lineOptsect" background="none" :ontouch="true" | |||
canvasId="wangxiaohuaerlingilingwuyiba1" :canvas2d="true" /> | |||
</template> | |||
</view> | |||
</view> | |||
<view class="" v-if="teamFlag"> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title" @click="staffShow1=true"> | |||
<view class="title1">团队接待趋势</view> | |||
<view class="title2"> | |||
<view class="title2-che" style="width: 220rpx;">{{team.label}} | |||
<image class="righttochoose" src="../../../static/images/righttochoose.png" mode=""></image> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="danwei">单位(%)</view> | |||
<view class="uchaserbox"> | |||
<qiun-data-charts type="line" :chartData="lineOptsect1" background="none" :ontouch="true" | |||
canvasId="wangxiaohuaerlineryiliwuyibao" :canvas2d="true" :opts="lineOpts" /> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="" v-if="staffFlag"> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1">员工接待趋势</view> | |||
<view class="title2" @click="staffShow=true"> | |||
<view class="title2-che" style="width: 220rpx;">{{staff.label}} | |||
<image class="righttochoose" src="../../../static/images/righttochoose.png" mode=""></image> | |||
</view> | |||
<!-- <view class="title2-che">执行率 | |||
<image class="righttochoose" src="../../../static/images/righttochoose.png" mode=""></image> | |||
</view> --> | |||
</view> | |||
</view> | |||
<!-- <view class="hejibox"> | |||
<view class="heji">合计:{{allnum1||0}}</view> | |||
<view class="heji">均值:{{allavg1||0}}</view> | |||
</view> --> | |||
<view class="danwei">单位(%)</view> | |||
<view class="uchaserbox"> | |||
<qiun-data-charts type="line" :chartData="lineOptsect2" background="none" :ontouch="true" | |||
canvasId="wangxiaohuaerlingeryilingwuyibao" :canvas2d="true" :opts="lineOpts" /> | |||
</view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1">场景触达分析</view> | |||
<!-- <view class="title3"> | |||
<view class="title3-box"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 0 }">执行率</view> | |||
</view> | |||
<view class="title3-box"> | |||
<view style="height: 42rpx;" :class="{ activecltab: activeTotal2 == 1 }">得分</view> | |||
</view> | |||
</view> --> | |||
</view> | |||
<!-- <view class="hejibox"> | |||
<view class="heji">合计:50</view> | |||
<view class="heji">均值:25</view> | |||
</view> --> | |||
<view style="width: 100%;height: 300rpx;text-align: center;line-height: 300rpx;" | |||
v-if="newlisttabinfo.length==0">暂无数据</view> | |||
<view v-else class="jindu" style="margin-top: 20rpx;"> | |||
<scroll-view style="height: 300rpx;" scroll-y="true"> | |||
<view class="jindu-box" v-for="(item,index) in newlisttabinfo" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name">{{item.name.substring(0, 4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#4FC78F" | |||
:percent="item.zxl"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}%</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
</view> | |||
</view> | |||
<view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view> | |||
<view class="single"> | |||
<view class="title"> | |||
<view class="title1">销讲指标执行率</view> | |||
</view> | |||
<view class="swiper-box"> | |||
<u-tabs-swiper ref="tabs" font-size="30" :bold="true" swiper-width="600" :current="bocindex1" | |||
@change="tapspagek3" inactive-color="#b1b1b1" active-color="#008ef2" :list="newlistoj" | |||
:is-scroll="true"> | |||
</u-tabs-swiper> | |||
</view> | |||
<view style="width: 100%;height: 300rpx;text-align: center;line-height: 300rpx;" | |||
v-if="newlisttabinfo1.length==0">暂无数据</view> | |||
<view class="jindu" v-else> | |||
<scroll-view style="height: 300rpx;" scroll-y="true"> | |||
<view class="jindu-box" v-for="(item,index) in newlisttabinfo1" :key="index"> | |||
<view class="jindu-boxche"> | |||
<view class="jindu-name">{{item.name.substring(0, 4)}}</view> | |||
<view style="width: 440rpx;margin-left: 10rpx;"> | |||
<u-line-progress height="24" :show-percent="false" active-color="#4FC78F" | |||
:percent="item.zxl"></u-line-progress> | |||
</view> | |||
<view class="jindu-zxl">{{item.zxl==null?0:item.zxl}}%</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
</view> | |||
</view> | |||
<u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> | |||
<u-select v-model="staffShow" :list="staffList" @confirm="staffSelectCallback($event,0)" | |||
:default-value='selindex'></u-select> | |||
<u-select v-model="staffShow1" :list="teamList" @confirm="staffSelectCallback($event,1)" | |||
:default-value='selindex'></u-select> | |||
</view> | |||
</template> | |||
<script> | |||
var app = getApp(); | |||
// var util = require("../../../utils/util.js"); | |||
var config = require("../../../config"); | |||
export default { | |||
data() { | |||
return { | |||
activeTotal: 4, | |||
activeTotal2: 0, | |||
houseId: '', | |||
timeobj: { | |||
statDateStart: '', | |||
statDateEnd: '' | |||
}, | |||
// 员工列表 | |||
staffList: [], | |||
// 团队列表 | |||
teamList: [], | |||
staffShow: false, | |||
staff: { | |||
value: '', | |||
label: '' | |||
}, | |||
team: { | |||
value: '', | |||
label: '' | |||
}, | |||
teamFlag: true, | |||
bocindex1: 0, | |||
staffFlag: true, | |||
staffShow1: false, | |||
lastStartDate: '', | |||
lastEndDate: '', | |||
allnum: '', | |||
allavg: '', | |||
allnum1: '', | |||
allavg1: '', | |||
danwei: '单位(次)', | |||
totalTimeShow: false, | |||
activeTab: 0, | |||
numlist: [ | |||
{ | |||
name: '接待量', | |||
num: '', | |||
setName: 'sumCustomer' | |||
},{ | |||
name: '有效接待', | |||
num: '', | |||
setName: 'receptionCount' | |||
}, | |||
{ | |||
name: '平均执行率', | |||
num: '', | |||
setName: 'fraction' | |||
}, | |||
{ | |||
name: '平均接待时长', | |||
num: '', | |||
setName: 'sumDuration' | |||
}, | |||
], | |||
lineOptsect: { | |||
"categories": ["2016", "2017", "2018", "2019", "2020", "2021"], | |||
"series": [{ | |||
"name": "成交量", | |||
"data": [35, 8, 25, 37, 4, 20] | |||
}] | |||
}, | |||
lineOptsect1: { | |||
"categories": [], | |||
"series": [] | |||
}, | |||
lineOptsect2: { | |||
"categories": ["2016", "2017", "2018", "2019", "2020", "2021"], | |||
"series": [{ | |||
"name": "成交量", | |||
"data": [35, 8, 25, 37, 4, 20] | |||
}] | |||
}, | |||
newlistoj: [], | |||
newlistoj1: [ | |||
{ | |||
name: "接待量", | |||
id: 3, | |||
title: '单位(个)', | |||
setName: 'sumCustomer' | |||
}, | |||
{ | |||
name: "有效接待", | |||
id: 1, | |||
title: '单位(次)', | |||
setName: 'receptionCount' | |||
}, | |||
{ | |||
name: "平均执行率", | |||
id: 2, | |||
title: '单位(%)', | |||
setName: 'fraction' | |||
}, | |||
{ | |||
name: "平均接待时长", | |||
id: 5, | |||
title: '单位(min)', | |||
setName: 'sumDuration' | |||
}, | |||
], | |||
bocindex: 0, | |||
newlisttabinfo: [{ | |||
name: '接待量', | |||
zxl: '10' | |||
}, | |||
{ | |||
name: '平均执行率', | |||
zxl: '50' | |||
}, | |||
{ | |||
name: '接待客户', | |||
zxl: '80' | |||
}, | |||
], | |||
newlisttabinfo1: [], | |||
Theteamcomparedisshow: false, | |||
Groupcontrastisshow: false, | |||
allechar: [], | |||
allList: [], | |||
lineOpts: { | |||
yAxis: { | |||
data: [{ | |||
max: 100, | |||
min: 0, | |||
}] | |||
} | |||
}, | |||
}; | |||
}, | |||
onShow() { | |||
// 获取项目id | |||
this.houseId = uni.getStorageSync('buildingID').id; | |||
// 获取数据看板 | |||
// 获取员工 | |||
this.getStaffList() | |||
// 获取团队 | |||
this.getSectionList() | |||
// 获取团队是否显示权限 | |||
this.queryHaveDept() | |||
// 获取简报 | |||
this.getReport() | |||
// 获取接待趋势 | |||
this.getRtrent() | |||
// 获取维度 | |||
this.getindexZxl() | |||
}, | |||
onPullDownRefresh() { | |||
// 获取员工 | |||
this.getStaffList() | |||
// 获取团队 | |||
this.getSectionList() | |||
// 获取团队是否显示权限 | |||
// 获取简报 | |||
this.getReport() | |||
// 获取接待趋势 | |||
this.getRtrent() | |||
// 获取维度 | |||
this.getindexZxl() | |||
setTimeout(function() { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
methods: { | |||
queryHaveDept() { | |||
return new Promise((resolve, reject) => { | |||
this.$u.get("/user/queryHaveDept?houseId=" + this.houseId).then(res => { | |||
this.permissions(res) | |||
}) | |||
}) | |||
}, | |||
permissions(res) { | |||
if (res == 1) { | |||
this.Theteamcomparedisshow = false; | |||
this.Groupcontrastisshow = false; | |||
return | |||
} | |||
let totle = uni.getStorageSync('weapp_session_userInfo_data').total; | |||
if (totle == 1) { | |||
this.Theteamcomparedisshow = true; | |||
this.Groupcontrastisshow = false; | |||
} else { | |||
this.Theteamcomparedisshow = true; | |||
this.Groupcontrastisshow = true; | |||
} | |||
}, | |||
// 获取员工列表 | |||
getStaffList() { | |||
this.$u.post('/cusLvStatistics/selectAllAccountIdByHouseId', { | |||
houseId: this.houseId | |||
}) | |||
.then(res => { | |||
// console.log(res,'123') | |||
this.staffList = [] | |||
res.map(item => { | |||
let obj = {} | |||
obj.value = item.accountId | |||
obj.label = item.name | |||
this.staffList.push(obj) | |||
}) | |||
this.staff = this.staffList[0] | |||
this.getAward() | |||
}) | |||
}, | |||
// 获取接待趋势 | |||
getRtrent() { | |||
this.$u.post('/cusLvStatistics/receptionTrend', { | |||
houseId: this.houseId, | |||
timeType: this.lastEndDate ? null : this.activeTotal, | |||
lastEndDate: this.lastEndDate, | |||
lastStartDate: this.lastStartDate | |||
}) | |||
.then(res => { | |||
// console.log(res) | |||
this.allechar = res | |||
this.tapspagek2(this.bocindex) | |||
}) | |||
}, | |||
// 销奖维度 | |||
getindexZxl() { | |||
this.$u.post('/cusLvStatistics/indexZxl', { | |||
houseId: this.houseId, | |||
timeType: this.lastEndDate ? null : this.activeTotal, | |||
lastEndDate: this.lastEndDate, | |||
lastStartDate: this.lastStartDate | |||
}) | |||
.then(res => { | |||
// console.log(res) | |||
// 处理销奖维度执行率 | |||
// this.newlisttabinfo | |||
let arr = [] | |||
this.newlistoj = [] | |||
res.list.map((item, index) => { | |||
arr.push({ | |||
name: item.name, | |||
zxl: item.zxl | |||
}) | |||
this.newlistoj.push({ | |||
name: item.name, | |||
id: index | |||
}) | |||
}) | |||
this.newlisttabinfo = arr | |||
this.allList = res.list | |||
this.tapspagek3(this.bocindex1) | |||
}) | |||
}, | |||
// 获取简报 | |||
getReport() { | |||
this.$u.post('/cusLvStatistics/xiaojiangAnalysis', { | |||
houseId: this.houseId, | |||
timeType: this.lastEndDate ? null : this.activeTotal, | |||
lastEndDate: this.lastEndDate, | |||
lastStartDate: this.lastStartDate | |||
}) | |||
.then(res => { | |||
res.sumDuration = Math.floor(res.sumDuration / 60) || 0 | |||
res.fraction = (res.fraction || 0) + '%' | |||
this.numlist.map(item => { | |||
item.num = res[item.setName] | |||
}) | |||
}) | |||
}, | |||
// 获取团队列表 | |||
getSectionList() { | |||
this.$u.post('/cusLvStatistics/findAllDeptIdByHouseId', { | |||
houseId: this.houseId | |||
}) | |||
.then(res => { | |||
this.teamList = [] | |||
res.map(item => { | |||
let obj = {} | |||
obj.value = item.deptId | |||
obj.label = item.deptName | |||
this.teamList.push(obj) | |||
}) | |||
this.team = this.teamList[0] | |||
this.receptionCountList() | |||
}) | |||
}, | |||
// 员工销奖趋势 | |||
getAward() { | |||
if (this.staffList.length == 0) { | |||
this.staffFlag = false | |||
this.$forceUpdate() | |||
return | |||
} | |||
this.$u.post('/cusLvStatistics/employeeAnalysisExacutiveRate', { | |||
userA: this.staff.value, | |||
userB: '', | |||
houseId: this.houseId, | |||
timeType: this.lastEndDate ? null : this.activeTotal + '', | |||
lastEndDate: this.lastEndDate, | |||
lastStartDate: this.lastStartDate | |||
}) | |||
.then(res => { | |||
this.allnum1 = res.avg[0] | |||
this.allavg1 = res.avg[1] | |||
// console.log(res) | |||
let first = res.first | |||
let second = res.second | |||
this.lineOptsect2.categories = [] | |||
this.lineOptsect2.series = [{ | |||
name: first[0].accountName, | |||
data: [] | |||
}] | |||
first.map(item => { | |||
this.lineOptsect2.categories.push(item.statDate.slice(5, 10)) | |||
this.lineOptsect2.series[0].data.push(item.sumFraction) | |||
}) | |||
}) | |||
}, | |||
// 团队接待趋势 | |||
receptionCountList() { | |||
if (this.teamList.length == 0) { | |||
this.teamFlag = false | |||
this.$forceUpdate() | |||
return | |||
} | |||
this.$u.post('/cusLvStatistics/teamAnalysisExecutionRate', { | |||
deptIds: this.team.value, | |||
showRank: 1, | |||
houseId: this.houseId, | |||
timeType: this.lastEndDate ? null : this.activeTotal + '', | |||
lastEndDate: this.lastEndDate, | |||
lastStartDate: this.lastStartDate | |||
}) | |||
.then(res => { | |||
// console.log(res) | |||
let result = res.result | |||
this.allnum = res.avg[0] | |||
this.allavg = res.avg[1] | |||
// 当选择趋势时 | |||
this.lineOptsect1 = {} | |||
let allobj = { | |||
categories: [], | |||
series: [] | |||
} | |||
// 先处理时间 | |||
// 当选择全部时 | |||
// 当选择只有一个时 | |||
let obj = {} | |||
obj.data = [] | |||
obj.name = result[0][0].deptName | |||
result[0].map(item => { | |||
allobj.categories.push(item.statDate.slice(5, 10)) | |||
obj.data.push(item.data) | |||
}) | |||
allobj.series.push(obj) | |||
this.lineOptsect1 = allobj | |||
}) | |||
}, | |||
//时间切换 | |||
tabtimetap(index) { | |||
if (index == 3) { | |||
this.totalTimeShow = true; | |||
} else { | |||
this.activeTotal = index; | |||
this.lastEndDate = '' | |||
this.lastStartDate = '' | |||
this.getdata() | |||
} | |||
}, | |||
// 获取数据 | |||
getdata() { | |||
this.receptionCountList() | |||
this.getReport() | |||
this.getRtrent() | |||
this.getindexZxl() | |||
this.getAward() | |||
}, | |||
staffSelectCallback(e, idx) { | |||
if (idx == 0) { | |||
this.staff = e[0] | |||
this.getAward() | |||
} else { | |||
this.team = e[0] | |||
this.receptionCountList() | |||
} | |||
// console.log(e,idx) | |||
}, | |||
//自定义时间 | |||
totalTimeChange(e) { | |||
console.log(e.startDate, e.endDate) | |||
this.activeTotal = 3; | |||
this.lastEndDate = e.endDate | |||
this.lastStartDate = e.startDate | |||
this.getdata() | |||
}, | |||
//指标执行率分析tab | |||
tapspagek2(index) { | |||
console.log(index) | |||
// 对数据进行分析和处理 | |||
// 先处理日期 | |||
let allobj = { | |||
"categories": [], | |||
"series": [{ | |||
name: '接待量', | |||
data: [] | |||
}] | |||
} | |||
this.danwei = this.newlistoj1[index].title | |||
allobj.series[0].name = this.newlistoj1[index].name | |||
this.allechar.map(item => { | |||
allobj.categories.push(item.statDate.slice(5, 10)) | |||
allobj.series[0].data.push(item[this.newlistoj1[index].setName]) | |||
}) | |||
this.bocindex = index; | |||
this.lineOptsect = allobj | |||
this.$forceUpdate() | |||
}, | |||
tapspagek3(index) { | |||
let arr = [] | |||
// return | |||
// console.log(index,this.allList[index]) | |||
this.allList[index].children.map(item => { | |||
arr.push({ | |||
name: item.name, | |||
zxl: item.zxl | |||
}) | |||
}) | |||
this.newlisttabinfo1 = arr | |||
this.bocindex1 = index; | |||
}, | |||
//集团对比 | |||
Groupcontrast() { | |||
uni.navigateTo({ | |||
url: '/pages/center/Piabodata/Groupcontrast' | |||
}); | |||
}, | |||
//团队对比 | |||
Theteamcompared() { | |||
if (this.teamList.length == 0) { | |||
uni.showToast({ | |||
title: '没有团队呢', | |||
icon: 'none' | |||
}) | |||
return | |||
} | |||
uni.navigateTo({ | |||
url: '/pages/center/Piabodata/Theteamcompared' | |||
}); | |||
}, | |||
//用户洞察 | |||
toUserinsightinto() { | |||
uni.navigateTo({ | |||
url: '/pages/center/Piabodata/Userinsightinto' | |||
}); | |||
}, | |||
//趋势分析 | |||
toTrendAnalysis() { | |||
uni.navigateTo({ | |||
url: '/pages/center/Piabodata/TrendAnalysis' | |||
}); | |||
}, | |||
//员工分析 | |||
toStaffAnalysis() { | |||
if (this.staffList.length == 0) { | |||
uni.showToast({ | |||
title: '没有团队呢', | |||
icon: 'none' | |||
}) | |||
return | |||
} | |||
uni.navigateTo({ | |||
url: '/pages/center/Piabodata/StaffAnalysis' | |||
}); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100%; | |||
height: 100%; | |||
background: #FAFAFA; | |||
padding-bottom: 60rpx; | |||
} | |||
.Piabodata-box { | |||
width: 100%; | |||
background: #FFFFFF; | |||
display: flex; | |||
flex-wrap: wrap; | |||
padding-bottom: 30rpx; | |||
.Piabodata { | |||
width: 33.3%; | |||
.Piabodata-img { | |||
width: 100%; | |||
text-align: center; | |||
.Piabodata-img1 { | |||
width: 134rpx; | |||
height: 134rpx; | |||
} | |||
} | |||
.Piabodata-text { | |||
width: 100%; | |||
text-align: center; | |||
font-size: 24rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
margin-top: -10rpx; | |||
} | |||
} | |||
} | |||
.grid:nth-child(1) { | |||
border-right: none; | |||
border-bottom: none; | |||
} | |||
.grid:nth-child(2) { | |||
border-bottom: none; | |||
} | |||
.grid:nth-child(3) { | |||
border-right: none; | |||
} | |||
</style> |
@@ -0,0 +1,151 @@ | |||
<template> | |||
<view class="box"> | |||
<!-- 顾问选择 --> | |||
<view class="nextcon"> | |||
最多选择五项 | |||
</view> | |||
<view class="content"> | |||
<scroll-view style="height: 1170rpx;" scroll-y="true" > | |||
<checkbox-group v-model="value" @change="checkboxChange"> | |||
<view v-for="(item,index) in items" :key="index"> | |||
<view class="content-tips"> | |||
<view class="left"> | |||
{{item.propertyName}} | |||
</view> | |||
<view class="right"> | |||
<radio :value="item.id" style="transform:scale(0.8)" color="#2671E2" :checked="item.checked" @click="addclick(index)"></radio> | |||
</view> | |||
</view> | |||
</view> | |||
</checkbox-group> | |||
</scroll-view> | |||
<view class="zhedang"></view> | |||
<view class="btn" @click="goback"> | |||
确定 | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data(){ | |||
return{ | |||
value:[], | |||
items:[], | |||
ids:'' | |||
} | |||
}, | |||
onLoad(e) { | |||
// 获取项目id | |||
// console.log(e) | |||
this.ids=e.ids | |||
// this.houseId = uni.getStorageSync('buildingID').id; | |||
this.getSectionList() | |||
}, | |||
methods:{ | |||
checkboxChange (e) { | |||
// console.log(e) | |||
}, | |||
// 获取部门列表 | |||
getSectionList(){ | |||
this.$u.post('/user/getHouseByToken',) | |||
.then(res=>{ | |||
// console.log(res) | |||
res.map((item,index)=>{ | |||
if(index<5){ | |||
item.checked=true | |||
}else{ | |||
item.checked=false | |||
} | |||
}) | |||
this.items=res | |||
// console.log(this.items) | |||
if(this.ids){ | |||
let arr=this.ids.split(',') | |||
this.items.map((item,index)=>{ | |||
let idx=arr.findIndex(item1=>item1==item.id) | |||
if(idx!=-1){ | |||
item.checked=true | |||
}else{ | |||
item.checked=false | |||
} | |||
}) | |||
} | |||
}) | |||
}, | |||
addclick(index){ | |||
this.items[index].checked=!this.items[index].checked | |||
}, | |||
goback(){ | |||
// 循环遍历所有选定的内容 | |||
let arr=[] | |||
this.items.map(item=>{ | |||
if(item.checked){ | |||
arr.push(item.id) | |||
} | |||
}) | |||
uni.$emit('updateGroup',{arr}) | |||
uni.navigateBack() | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box{ | |||
background: #F8F8F8; | |||
width: 100%; | |||
height: 100%; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
// line-height: 30px; | |||
.nextcon{ | |||
height: 78rpx; | |||
background: #F4F8FD; | |||
color: #2671E2; | |||
text-align: center; | |||
line-height: 78rpx; | |||
} | |||
.content-tips{ | |||
display: flex; | |||
justify-content: space-between; | |||
background: #fff; | |||
padding: 0 30rpx; | |||
height: 92rpx; | |||
margin-bottom: 20rpx; | |||
.left{ | |||
display: flex; | |||
// margin-top: 30rpx; | |||
font-weight: 500; | |||
color: #303030; | |||
line-height: 92rpx; | |||
font-size: 30rpx; | |||
} | |||
.right{ | |||
margin: 24rpx 0; | |||
} | |||
} | |||
.btn{ | |||
width: 690rpx; | |||
height: 88rpx; | |||
background: #2671E2; | |||
border-radius: 8rpx; | |||
font-size: 32rpx; | |||
font-weight: 400; | |||
color: #FFFFFF; | |||
line-height: 88rpx; | |||
text-align: center; | |||
position: fixed; | |||
left: 30rpx; | |||
bottom: 80rpx; | |||
} | |||
.zhedang{ | |||
height: 168rpx; | |||
opacity: 0; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,150 @@ | |||
<template> | |||
<view class="box"> | |||
<!-- 顾问选择 --> | |||
<view class="nextcon"> | |||
最多选择五项 | |||
</view> | |||
<view class="content"> | |||
<scroll-view style="height: 1170rpx;" scroll-y="true" > | |||
<checkbox-group v-model="value" @change="checkboxChange"> | |||
<view v-for="(item,index) in items" :key="index"> | |||
<view class="content-tips"> | |||
<view class="left"> | |||
{{item.deptName}} | |||
</view> | |||
<view class="right"> | |||
<radio :value="item.deptId" style="transform:scale(0.8)" color="#2671E2" :checked="item.checked" @click="addclick(index)"></radio> | |||
</view> | |||
</view> | |||
</view> | |||
</checkbox-group> | |||
</scroll-view> | |||
<view class="zhedang"></view> | |||
<view class="btn" @click="goback"> | |||
确定 | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data(){ | |||
return{ | |||
value:[], | |||
items:[], | |||
ids:'' | |||
} | |||
}, | |||
onLoad(e) { | |||
// 获取项目id | |||
// console.log(e) | |||
this.ids=e.ids | |||
this.houseId = uni.getStorageSync('buildingID').id; | |||
this.getSectionList() | |||
}, | |||
methods:{ | |||
checkboxChange (e) { | |||
// console.log(e) | |||
}, | |||
// 获取部门列表 | |||
getSectionList(){ | |||
this.$u.post('/cusLvStatistics/findAllDeptIdByHouseId',{houseId:this.houseId}) | |||
.then(res=>{ | |||
console.log(res) | |||
res.map((item,index)=>{ | |||
if(index<5){ | |||
item.checked=true | |||
}else{ | |||
item.checked=false | |||
} | |||
}) | |||
this.items=res | |||
if(this.ids){ | |||
let arr=this.ids.split(',') | |||
this.items.map((item,index)=>{ | |||
let idx=arr.findIndex(item1=>item1==item.deptId) | |||
if(idx!=-1){ | |||
item.checked=true | |||
}else{ | |||
item.checked=false | |||
} | |||
}) | |||
} | |||
}) | |||
}, | |||
addclick(index){ | |||
this.items[index].checked=!this.items[index].checked | |||
}, | |||
goback(){ | |||
// 循环遍历所有选定的内容 | |||
let arr=[] | |||
this.items.map(item=>{ | |||
if(item.checked){ | |||
arr.push(item.deptId) | |||
} | |||
}) | |||
uni.$emit('update',{arr}) | |||
uni.navigateBack() | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box{ | |||
background: #F8F8F8; | |||
width: 100%; | |||
height: 100%; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
// line-height: 30px; | |||
.nextcon{ | |||
height: 78rpx; | |||
background: #F4F8FD; | |||
color: #2671E2; | |||
text-align: center; | |||
line-height: 78rpx; | |||
} | |||
.content-tips{ | |||
display: flex; | |||
justify-content: space-between; | |||
background: #fff; | |||
padding: 0 30rpx; | |||
height: 92rpx; | |||
margin-bottom: 20rpx; | |||
.left{ | |||
display: flex; | |||
// margin-top: 30rpx; | |||
font-weight: 500; | |||
color: #303030; | |||
line-height: 92rpx; | |||
font-size: 30rpx; | |||
} | |||
.right{ | |||
margin: 24rpx 0; | |||
} | |||
} | |||
.btn{ | |||
width: 690rpx; | |||
height: 88rpx; | |||
background: #2671E2; | |||
border-radius: 8rpx; | |||
font-size: 32rpx; | |||
font-weight: 400; | |||
color: #FFFFFF; | |||
line-height: 88rpx; | |||
text-align: center; | |||
position: fixed; | |||
left: 30rpx; | |||
bottom: 80rpx; | |||
} | |||
.zhedang{ | |||
height: 168rpx; | |||
opacity: 0; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,495 @@ | |||
<template> | |||
<view class="box"> | |||
<!-- 编辑 --> | |||
<view class="conmsg"> | |||
<view class="conmsg-title"> | |||
客户信息 | |||
</view> | |||
<view class="conmsg-msg"> | |||
<view class="conmsg-msg-lab"> | |||
<view class="conmsg-msg-lab-1"> | |||
客户姓名 | |||
<view class="star"> | |||
* | |||
</view> | |||
</view> | |||
<view class="conmsg-msg-lab-inp"> | |||
<input type="text" placeholder="请输入客户姓名" placeholder-style="color:#B2B2B2;" | |||
v-model="form.name" /> | |||
</view> | |||
</view> | |||
<view class="conmsg-msg-lab"> | |||
<view class="conmsg-msg-lab-1"> | |||
客户性别 | |||
</view> | |||
<view class="conmsg-msg-lab-inp" style="margin-top: 20rpx;"> | |||
<view style="border: none; display: flex;"> | |||
<view class="sexchose" @click="form.sex=1" | |||
:style="{border:form.sex==1?'1px solid #0A6EE9':'1px solid #E0E0E0'}"> | |||
男 | |||
</view> | |||
<view class="sexchose" @click="form.sex=2" | |||
:style="{border:form.sex==2?'1px solid #0A6EE9':'1px solid #E0E0E0'}"> | |||
女 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="conmsg-msg-lab"> | |||
<view class="conmsg-msg-lab-1"> | |||
联系电话 | |||
</view> | |||
<view class="conmsg-msg-lab-inp"> | |||
<input type="number" @focus="callPhoneFocus" @blur="callPhoneBlur" placeholder="请输入联系电话" placeholder-style="color:#B2B2B2;" maxlength="11" | |||
v-model="form.showPhone" /> | |||
</view> | |||
</view> | |||
<view class="conmsg-msg-lab"> | |||
<view class="conmsg-msg-lab-1"> | |||
微信账号 | |||
</view> | |||
<view class="conmsg-msg-lab-inp"> | |||
<input type="text" placeholder="请输入微信账号" placeholder-style="color:#B2B2B2;" | |||
v-model="form.chatNo" /> | |||
</view> | |||
</view> | |||
<view class="conmsg-msg-lab" @click="levelshow = true"> | |||
<view class="conmsg-msg-lab-1"> | |||
客户等级 | |||
</view> | |||
<view class="conmsg-msg-lab-inp"> | |||
<input type="text" placeholder="请选择客户等级" v-model="selectform.level" disabled /> | |||
</view> | |||
<view class="conmsg-msg-lab-img"> | |||
<image class="screen-sel-img" src="../../../static/images/right.png" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="conmsg-msg-lab"> | |||
<view class="conmsg-msg-lab-1"> | |||
客户来源 | |||
</view> | |||
<view class="conmsg-msg-lab-inp"> | |||
<input type="text" placeholder="请选择客户来源" @click="Buildingselection" v-model="form.sourceName" | |||
disabled /> | |||
</view> | |||
<view class="conmsg-msg-lab-img"> | |||
<image class="screen-sel-img" src="../../../static/images/right.png" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="conmsg-msg-lab" style="border: none;"> | |||
<view class="conmsg-msg-lab-1"> | |||
备注内容 | |||
</view> | |||
<view class="conmsg-msg-lab-inp"> | |||
<input type="text" placeholder="请输入备注内容" placeholder-style="color:#B2B2B2;" | |||
v-model="form.remarks" /> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="conmsg" v-if="allList.length!=0"> | |||
<view class="conmsg-title"> | |||
客户标签 | |||
</view> | |||
<view class="conmsg-msg"> | |||
<view v-for="(item,index) in allList" :key="index"> | |||
<view class=""> | |||
<view class="conmsg-msg-lab" style="border: none;"> | |||
<view class="conmsg-msg-lab-1"> | |||
{{item.name}} | |||
</view> | |||
</view> | |||
<view class="con-msg-con" | |||
:style="{borderBottom:index==allList.length-1?'none':'1px solid #E0E0E0'}"> | |||
<view v-for="(item1,i) in item.children" :key="i" @click="Edittag(item,item1,index,i)" | |||
:style="{border:item1.selected==0?'1px solid #0A6EE9':'1px solid #E0E0E0'}" | |||
class="chebox"> | |||
{{item1.label}} | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="submit"> | |||
<view class="btn" @click="submit"> | |||
确定 | |||
</view> | |||
</view> | |||
<view class="" style="height: 220rpx;"> | |||
<!-- :style="{marginTop:allList.length!=0?'0':'500rpx'}" --> | |||
</view> | |||
<!-- 客户等级 --> | |||
<u-select v-model="levelshow" :list="levellist" @confirm="levelshowCallback"></u-select> | |||
<u-select :mask-close-able="false" label-name="sourceName" value-name="id" v-model="Showhiddenunits" | |||
mode="single-column" :list="list" @cancel="cancel" @confirm="confirm"></u-select> | |||
</view> | |||
</template> | |||
<script> | |||
const config = require("@/config"); | |||
export default { | |||
data() { | |||
return { | |||
Showhiddenunits: false, // 控制客户来源弹窗 | |||
form: { | |||
name: '', | |||
sex: '1', | |||
phone: '', | |||
chatNo: '', | |||
level: '1', | |||
remarks: '', | |||
sourceId: '' | |||
}, | |||
selectform: { | |||
level: 'A', | |||
stage: '', | |||
demand: '', | |||
area: '', | |||
budget: '', | |||
fouce: '', | |||
soure: '', | |||
}, | |||
list: [], // 客户来源数组 | |||
levelshow: false, | |||
customerId: '', | |||
// 等级 | |||
levellist: [{ | |||
value: 1, | |||
label: 'A' | |||
}, | |||
{ | |||
value: 2, | |||
label: 'B' | |||
}, | |||
{ | |||
value: 3, | |||
label: 'C' | |||
}, | |||
{ | |||
value: 4, | |||
label: 'D' | |||
}, | |||
], | |||
allList: [], | |||
dataCode: '', | |||
projectId: '', // 项目ID | |||
userInfo: {}, // 当前用户信息 | |||
} | |||
}, | |||
onLoad(e) { | |||
this.userInfo = uni.getStorageSync("weapp_session_userInfo_data"); | |||
console.log() | |||
this.dataCode = this.userInfo.dataCode | |||
console.log(e) | |||
// 先调用借口查询数据 | |||
this.customerId = e.id | |||
if (e.projectId) this.projectId = e.projectId | |||
this.getdetail() | |||
this.getFromSource() | |||
}, | |||
methods: { | |||
// 获取客户来源 | |||
getFromSource() { | |||
uni.request({ | |||
url: config.service.sourceList + "?houseId=" + this.projectId, | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
console.log(data) | |||
if (data.data.code == 10000) { | |||
this.list = data.data.data | |||
} | |||
}, | |||
fail: (res) => { | |||
console.log(res) | |||
} | |||
}) | |||
}, | |||
// 选择客户来源 | |||
Buildingselection() { | |||
this.Showhiddenunits = true; | |||
}, | |||
cancel() { | |||
this.Showhiddenunits = false; | |||
}, | |||
confirm(e) { | |||
this.form.sourceName = e[0].label; | |||
this.form.sourceId = e[0].value; | |||
this.Showhiddenunits = false; | |||
}, | |||
Edittag(item, item1, index, i) { | |||
if (this.allList[index].children[i].selected == 0) { | |||
this.allList[index].children[i].selected = 1; | |||
} else { | |||
this.allList[index].children[i].selected = 0; | |||
} | |||
this.$forceUpdate() | |||
}, | |||
sourecheck(index) { | |||
this.sourelist[index].checked = !this.sourelist[index].checked | |||
this.$forceUpdate() | |||
}, | |||
demandcheck(index) { | |||
this.demandlist[index].checked = !this.demandlist[index].checked | |||
this.$forceUpdate() | |||
}, | |||
areacheck(index) { | |||
this.arealist[index].checked = !this.arealist[index].checked | |||
this.$forceUpdate() | |||
}, | |||
levelshowCallback(e) { | |||
this.selectform.level = e[0].label | |||
this.form.level = e[0].value | |||
}, | |||
// 获取用户数据 | |||
getdetail() { | |||
this.$u.get("customer/findById?", { | |||
id: this.customerId | |||
}) | |||
.then(res => { | |||
this.form = res | |||
if (!this.form.phone) { | |||
this.form.showPhone = '--' | |||
} else { | |||
if (this.form.isShow == 1 && this.form.phone.length == 11) { | |||
this.form.showPhone = this.form.phone.substr(0, 3) + '****' + this.form.phone.substr(7) | |||
} else { | |||
this.form.showPhone = this.form.phone | |||
} | |||
} | |||
this.form.showPhones = this.form.showPhone | |||
// 给客户等级赋值 | |||
let idx = this.levellist.findIndex(item => item.value == res.level) | |||
if (idx != -1) { | |||
this.selectform.level = this.levellist[idx].label | |||
} else { | |||
this.selectform.level = 'A'; | |||
this.form.level = 1; | |||
} | |||
this.showSourceName = res.sourceName; | |||
// 获取置业需求 | |||
this.getListByType() | |||
}) | |||
}, | |||
// 字典表接口 | |||
getListByType() { | |||
this.$u.get("/matchKeywords/findPersonalMatchData", { | |||
customerId: this.customerId | |||
}) | |||
.then(res => { | |||
// console.log(res) | |||
res.forEach(item1 => { | |||
item1.children.map(item => { | |||
if (item.isInterval == 0) { | |||
item.label = item.name + item.unit + '-' + item.endName + item | |||
.unit; | |||
} else { | |||
item.label = item.name | |||
} | |||
item.value = item.id; | |||
}) | |||
}) | |||
// console.log(res) | |||
this.allList = res | |||
// return | |||
}) | |||
}, | |||
// 输入框获取焦点 | |||
callPhoneFocus() { | |||
if (this.form.isShow == 1 && this.form.showPhone == this.form.showPhones) { | |||
this.form.showPhone = '' | |||
this.$forceUpdate() | |||
} | |||
}, | |||
// 输入框失去焦点 | |||
callPhoneBlur() { | |||
if (this.form.isShow == 1 && this.form.showPhone == '') { | |||
this.form.showPhone = this.form.showPhones | |||
this.$forceUpdate() | |||
} | |||
}, | |||
// 提交 | |||
submit() { | |||
let param = {} | |||
let str = [] | |||
if (this.form.name == '') { | |||
uni.showToast({ | |||
title: '请输入客户姓名', | |||
icon: 'none' | |||
}) | |||
return | |||
} | |||
if (this.form.showPhones != this.form.showPhone) { | |||
this.form.phone = this.form.showPhone | |||
} | |||
this.allList.map(item => { | |||
item.children.map(item1 => { | |||
if (item1.selected == 0) { | |||
str.push(item1.keywordsId) | |||
} | |||
}) | |||
}) | |||
str = str.join(',') | |||
param = this.form | |||
param.keywordIds = str | |||
console.log(param) | |||
// return | |||
this.$u.post("customer/update", param) | |||
.then(res => { | |||
// console.log(res) | |||
uni.showToast({ | |||
title: '操作成功', | |||
icon: 'none', | |||
success: () => { | |||
uni.navigateBack() | |||
} | |||
}) | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100%; | |||
height: 100%; | |||
background: #F8F8F8; | |||
overflow: hidden; | |||
} | |||
.conmsg { | |||
background: #FFFFFF; | |||
margin-top: 20rpx; | |||
.conmsg-title { | |||
height: 92rpx; | |||
line-height: 92rpx; | |||
font-weight: bold; | |||
padding: 0 30rpx; | |||
// font-weight: 500; | |||
color: #303030; | |||
font-size: 32rpx; | |||
border-bottom: 1px solid #E0E0E0; | |||
} | |||
.conmsg-msg { | |||
padding: 0 30rpx; | |||
.conmsg-msg-lab { | |||
height: 102rpx; | |||
display: flex; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
border-bottom: 1px solid #E0E0E0; | |||
line-height: 102rpx; | |||
.conmsg-msg-lab-1 { | |||
display: flex; | |||
min-width: 136rpx; | |||
.star { | |||
color: #E7483C; | |||
line-height: 108rpx; | |||
} | |||
} | |||
.conmsg-msg-lab-inp { | |||
margin-top: 30rpx; | |||
margin-left: 44rpx; | |||
} | |||
.conmsg-msg-lab-img { | |||
width: 14rpx; | |||
height: 30rpx; | |||
margin-top: 6rpx; | |||
margin-left: auto; | |||
image { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
.submit { | |||
position: fixed; | |||
bottom: 20rpx; | |||
left: 20rpx; | |||
height: 120rpx; | |||
background: #FFFFFF; | |||
.btn { | |||
// margin: 60rpx auto; | |||
text-align: center; | |||
width: 690rpx; | |||
height: 88rpx; | |||
background: #2671E2; | |||
border-radius: 8rpx; | |||
font-size: 32tpx; | |||
font-weight: 400; | |||
color: #FFFFFF; | |||
line-height: 88rpx; | |||
} | |||
} | |||
.con-msg-con { | |||
display: flex; | |||
flex-wrap: wrap; | |||
// justify-content: space-around; | |||
border-bottom: 1px solid #E0E0E0; | |||
padding-bottom: 16rpx; | |||
.chebox { | |||
// width: 20%; | |||
height: 60rpx; | |||
line-height: 60rpx; | |||
// margin: 10rpx 0; | |||
margin-bottom: 25rpx; | |||
margin-right: 20rpx; | |||
border: 1px solid #E0E0E0; | |||
box-sizing: border-box; | |||
padding: 0 10rpx; | |||
} | |||
} | |||
.sexchose { | |||
width: 120rpx; | |||
height: 60rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #E0E0E0; | |||
text-align: center; | |||
line-height: 60rpx; | |||
margin-right: 20rpx; | |||
} | |||
</style> |
@@ -0,0 +1,322 @@ | |||
<template> | |||
<view class="box"> | |||
<view class="screen"> | |||
<!-- 录音标示 --> | |||
<view class="screen-record"> | |||
<view class="screen-record-text"> | |||
最新状态 | |||
</view> | |||
<view class="screen-record-tab"> | |||
<scroll-view scroll-x style="width: 100%;"> | |||
<view style="display: flex;"> | |||
<block v-for="(item,index) in stateList" :key="index"> | |||
<view style="flex-shrink: 0;" | |||
:class="[screen.state==index?'screen-record-chose':'screen-record-nochose']" | |||
@click="screen.state=index"> | |||
{{item.stageName}} | |||
</view> | |||
</block> | |||
</view> | |||
</scroll-view> | |||
</view> | |||
</view> | |||
<!-- 录音标示 --> | |||
<view class="screen-record"> | |||
<view class="screen-record-text"> | |||
意向级别 | |||
</view> | |||
<view class="screen-record-tab"> | |||
<view :class="[screen.level==1?'screen-record-chose':'screen-record-nochose']" | |||
@click="screen.level=1"> | |||
A | |||
</view> | |||
<view :class="[screen.level==2?'screen-record-chose':'screen-record-nochose']" | |||
@click="screen.level=2"> | |||
B | |||
</view> | |||
<view :class="[screen.level==3?'screen-record-chose':'screen-record-nochose']" | |||
@click="screen.level=3"> | |||
C | |||
</view> | |||
<view :class="[screen.level==4?'screen-record-chose':'screen-record-nochose']" | |||
@click="screen.level=4"> | |||
D | |||
</view> | |||
</view> | |||
</view> | |||
<!-- <view class="screen-record" style="height: auto;"> | |||
<view class="screen-record-text" style="margin-bottom: 20rpx;"> | |||
客户类型 | |||
</view> | |||
<u-search placeholder="请输入搜索" v-model="keyword" :clearabled="true" :show-action="false" @change="search"></u-search> | |||
<scroll-view style="height: 180rpx;" scroll-y="true" > | |||
<view class="screen-record-tab" style="flex-wrap: wrap;"> | |||
<view v-for="(item,index) in customerType" :key="index"> | |||
<view :class="[item.check?'screen-record-chose':'screen-record-nochose']" style="margin-bottom: 20rpx;" @click="checkbox(index)"> | |||
{{item.keywords}} | |||
</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
</view> --> | |||
<view class="screen-record"> | |||
<view class="screen-record-text"> | |||
跟进内容 | |||
</view> | |||
<view class="screen-record-tab"> | |||
<input type="text" placeholder="请输入跟进内容" v-model="screen.con" /> | |||
</view> | |||
</view> | |||
<view class="screen-foot"> | |||
<view class="screen-foot-sure" @click="screensure"> | |||
保存 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
value: '', | |||
screenShow: false, | |||
selectshow: false, | |||
selectTipshow: false, | |||
buildingID: '', | |||
keyword: '', | |||
screen: { | |||
state: '0', | |||
con: "", | |||
level: '1' | |||
}, | |||
stateList: [], | |||
recordList: [], | |||
nextPage: 1, | |||
totalRecord: '', | |||
freeList: [], | |||
customerType: [], | |||
customerId: '' | |||
} | |||
}, | |||
onShow() { | |||
}, | |||
onLoad(e) { | |||
this.customerId = e.id | |||
this.buildingID = uni.getStorageSync('buildingID').id; | |||
this.recordList = [] | |||
// this.getMyCustom() | |||
// this.getFreeList() | |||
this.getNewStatus() | |||
this.getCustomerType(); | |||
}, | |||
methods: { | |||
//选择顾问 | |||
actionSelectCallback(e) { | |||
this.screen.agentId = e[0].value; | |||
this.screen.agentIdtext = e[0].label; | |||
}, | |||
getCustomerType() { | |||
this.$u.get("/customer/queryKeyWords").then(res => { | |||
res.map(item => { | |||
item.check = false | |||
}) | |||
this.customerType = res; | |||
}) | |||
}, | |||
getNewStatus() { | |||
var that = this; | |||
let premo = { | |||
houseId: uni.getStorageSync('buildingID').id | |||
} | |||
this.$u.post('/customer/getStage', premo) | |||
.then(res => { | |||
this.stateList = res | |||
}) | |||
}, | |||
checkbox(idx) { | |||
console.log(idx) | |||
this.customerType[idx].check = !this.customerType[idx].check | |||
}, | |||
search(e) { | |||
console.log(e) | |||
}, | |||
//选择标签 | |||
selectCallback(e) { | |||
console.log(e[0].label) | |||
}, | |||
//筛选确认 | |||
screensure() { | |||
// 获取选择过的数据 | |||
// let type=[] | |||
let words = [] | |||
this.customerType.map(item => { | |||
if (item.check) { | |||
// type.push(item.id) | |||
words.push(item.keywords) | |||
} | |||
}) | |||
// if (words.length == 0 ) { | |||
// uni.showModal({ | |||
// title: '提示', | |||
// content: '请选择、类型', | |||
// showCancel: false | |||
// }); | |||
// return; | |||
// } | |||
uni.showLoading({ | |||
title: "保存中~", | |||
mask: true | |||
}) | |||
// console.log(type) | |||
let param = { | |||
"stageCode": this.stateList[this.screen.state].stageCode, | |||
"stageName": this.stateList[this.screen.state].stageName, | |||
"remarks": this.screen.con, | |||
words, | |||
// "settingTime":"", | |||
"agentRelationPo": { | |||
"customerId": this.customerId, | |||
"level": this.screen.level, | |||
"state": this.stateList[this.screen.state].id | |||
} | |||
} | |||
this.$u.post('/customer/addZkDailyWorkRecord', param) | |||
.then(res => { | |||
// util.showSuccess("提交成功"); | |||
uni.hideLoading(); | |||
uni.navigateBack(); | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100%; | |||
height: 100%; | |||
background: #F8F8F8; | |||
} | |||
.screen { | |||
// box-sizing: border-box; | |||
// padding: 0 30rpx; | |||
background: #FFFFFF; | |||
.screen-counselor { | |||
display: flex; | |||
height: 106rpx; | |||
// padding: 40rpx 30rpx 36rpx 30rpx; | |||
padding: 0 30rpx; | |||
box-sizing: border-box; | |||
border-bottom: 1px solid #CCCCCC; | |||
.screen-text { | |||
margin: 40rpx 0 36rpx 0; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
line-height: 30rpx; | |||
} | |||
.screen-sel { | |||
display: flex; | |||
justify-content: space-between; | |||
width: 500rpx; | |||
margin-left: 60rpx; | |||
.screen-sel-img { | |||
margin: 40rpx 0 36rpx 0; | |||
width: 14rpx; | |||
height: 30rpx; | |||
} | |||
.screen-inp { | |||
margin-top: 20rpx; | |||
} | |||
} | |||
} | |||
.screen-record { | |||
height: 192rpx; | |||
// width: 100%; | |||
overflow: hidden; | |||
padding: 0 30rpx; | |||
box-sizing: border-box; | |||
border-bottom: 1px solid #CCCCCC; | |||
.screen-record-text { | |||
margin-top: 36rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
line-height: 30rpx; | |||
} | |||
.screen-record-tab { | |||
margin-top: 30rpx; | |||
display: flex; | |||
// justify-content: space-around; | |||
.screen-record-chose { | |||
width: 151rpx; | |||
height: 60rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #2671E2; | |||
text-align: center; | |||
line-height: 60rpx; | |||
margin-right: 22rpx; | |||
} | |||
.screen-record-nochose { | |||
width: 151rpx; | |||
height: 60rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #C9C9C9; | |||
text-align: center; | |||
line-height: 60rpx; | |||
margin-right: 22rpx; | |||
} | |||
} | |||
} | |||
.screen-foot { | |||
height: 88rpx; | |||
display: flex; | |||
width: 100%; | |||
margin-top: 160rpx; | |||
.screen-foot-reset { | |||
width: 80%; | |||
text-align: center; | |||
margin: 0 auto; | |||
line-height: 88rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
} | |||
.screen-foot-sure { | |||
width: 80%; | |||
margin: 0 auto; | |||
text-align: center; | |||
line-height: 88rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #FFFFFF; | |||
background: #2671E2; | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,773 @@ | |||
<template> | |||
<view class="box"> | |||
<!-- 选择器 --> | |||
<view class="boxtittab"> | |||
<view class="tabbox" @click="taptimeisshow"> | |||
{{ timeText }} | |||
<u-icon name="arrow-down" size="24" style="padding-left: 12rpx;"></u-icon> | |||
</view> | |||
<view class="tabbox" @click="selectshow = true"> | |||
{{ guwenText }} | |||
<u-icon name="arrow-down" size="24" style="padding-left: 12rpx;"></u-icon> | |||
</view> | |||
<view class="tabbox" @click="tapsoltishow"> | |||
{{ steyStatus }} | |||
<u-icon name="arrow-down" size="24" style="padding-left: 12rpx;"></u-icon> | |||
</view> | |||
<view class="tabbox" @click="showIdent = true"> | |||
{{ weijinTag }} | |||
<u-icon name="arrow-down" size="24" style="padding-left: 12rpx;"></u-icon> | |||
</view> | |||
</view> | |||
<view class="count" v-if="recordList.length > 0"> | |||
筛选结果:<text>{{totalRecords}} </text>条 | |||
</view> | |||
<view class="content"> | |||
<view v-if="recordList.length==0" | |||
style="width: 100%;height: 100%;display: flex;align-items: center;background: #FFFFFF;"> | |||
<view style="width: 100%;padding-top: 200rpx;"> | |||
<view style="width: 100%;text-align: center;"> | |||
<image style="width: 220rpx;height: 200rpx;" | |||
src="https://static.quhouse.com/zhikong_xcx_img/nodatalist.png" mode=""></image> | |||
</view> | |||
<view style="text-align: center;width: 100%;margin-top: 20rpx;color: #999999;">暂无数据</view> | |||
</view> | |||
</view> | |||
<view v-if="recordList.length!=0" class="content-tips" v-for="(item,index) in recordList" :key='index' | |||
@click="tapThevisiting(item, index)"> | |||
<view class="content-first"> | |||
<view class="left"> | |||
<view class="img">顾</view> | |||
<view class="name">{{item.agentName}}</view> | |||
<view class="status" v-if="item.replaceReception==1">代接待</view> | |||
</view> | |||
<view class="right"> | |||
<view class=""> | |||
{{ item.violatedStatus | ViolatedStatus }}|{{ item.disposeStatus | DisposeStatus }} | |||
</view> | |||
</view> | |||
</view> | |||
<view class="content-last"> | |||
<view class="item"> | |||
<image src="@/static/images/img/time.png" mode=""></image> | |||
<text>{{item.createTime}}</text> | |||
</view> | |||
<view class="item"> | |||
<image src="@/static/images/img/voice.png" mode=""></image> | |||
<text>{{item.mm || '0'}}min</text> | |||
</view> | |||
<view class="item"> | |||
<image src="@/static/images/img/hit.png" mode=""></image> | |||
<text>{{item.violatedFrequency || '0'}}</text> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 选择顾问的选择框 --> | |||
<u-select v-model="selectshow" :list="freeList" @confirm="actionSelectCallback"></u-select> | |||
<u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar> | |||
<u-popup v-model="timeshow" mode="bottom"> | |||
<block v-for="(data, index) in activeList" :key="index"> | |||
<view class="timeview" :style="{ color: activeTotal == data.id ? '#2B6EFF' : '#333333' }" | |||
@click="tabtimetap(data.id, data.title)">{{ data.title }}</view> | |||
</block> | |||
</u-popup> | |||
<u-select v-model="soltishow" :list="orderBylist" @confirm="selectCallback2"></u-select> | |||
<u-select v-model="showIdent" :list="identList" @confirm="selectIdent"></u-select> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
orderBylist: [{ | |||
label: '全部', | |||
value: null | |||
}, { | |||
label: '待处理', | |||
value: 0 | |||
}, { | |||
label: '已处理', | |||
value: 1 | |||
}], | |||
activeTotal: 5, | |||
activeList: [ // 时间筛选数组 | |||
{ | |||
title: '全部', | |||
id: 5, | |||
}, | |||
{ | |||
title: '今天', | |||
id: 0, | |||
}, | |||
{ | |||
title: '昨天', | |||
id: 1, | |||
}, | |||
{ | |||
title: '近7天', | |||
id: 2, | |||
}, | |||
{ | |||
title: '近30天', | |||
id: 3, | |||
}, | |||
{ | |||
title: '自定义', | |||
id: 4, | |||
}, | |||
], | |||
showIdent: false, // 显示选择违禁标识列表 | |||
identList: [ // 违禁标识列表 | |||
{ | |||
label: '全部', | |||
value: null | |||
}, | |||
{ | |||
label: '有效', | |||
value: 1 | |||
}, | |||
{ | |||
label: '无效', | |||
value: 2 | |||
}, | |||
], | |||
violatedStatus: null, // 违禁状态 | |||
selectshow: false, | |||
totalTimeShow: false, | |||
screen: { | |||
agentId: '', //顾问id | |||
record: '0', | |||
}, | |||
freeList: [], //顾问 | |||
recordList: [], | |||
buildingID: '', | |||
nextPage: 1, | |||
totalRecord: "", | |||
staTime: '', | |||
endtime: '', | |||
isnorefresh: '', | |||
activeTotal2: 0, | |||
timeshow: false, | |||
soltishow: false, | |||
orderBy: null, | |||
userInfo: {}, | |||
totalRecords: '', // 列表全部的条数 | |||
isRefresh: false, | |||
nextPageObj: {}, // 跳转详情页面的参数 | |||
// 页面文字展示内容 | |||
timeText: '接待时间', // | |||
guwenText: '顾问', // | |||
steyStatus: '处理状态', // | |||
weijinTag: '违禁标识', // 违禁标识 | |||
} | |||
}, | |||
onLoad(options) { | |||
this.isnorefresh = options.refresh; | |||
if (options.activeTotal) { | |||
this.activeTotal = options.activeTotal | |||
} | |||
if (options.staTime) { | |||
this.staTime = options.staTime; | |||
this.endtime = options.endtime; | |||
} | |||
if (options.violatedStatus) this.violatedStatus = options.violatedStatus | |||
}, | |||
onShow() { | |||
this.userInfo = uni.getStorageSync('weapp_session_userInfo_data'); | |||
if (this.isnorefresh == 'refresh') { | |||
this.buildingID = uni.getStorageSync('buildingID').id; | |||
this.recordList = []; | |||
this.nextPage = 1; | |||
this.isRefresh = false; | |||
this.getMyCustom() | |||
this.getFreeList(); | |||
this.isnorefresh = ''; | |||
} | |||
var pages = getCurrentPages(); | |||
pages[0].$vm.path = '/pages/index/index' | |||
console.log(pages[0].$vm.path) | |||
}, | |||
onPullDownRefresh() { | |||
this.nextPage = 1; | |||
this.isRefresh = true; | |||
this.getMyCustom() | |||
this.resetRefreshParams() | |||
setTimeout(function() { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
onReachBottom() { | |||
if (this.totalRecord == this.nextPage) { | |||
uni.showToast({ | |||
icon: 'none', | |||
title: '到底了', | |||
duration: 2000 | |||
}); | |||
return | |||
} else { | |||
this.nextPage += 1; | |||
this.isRefresh = false; | |||
this.getMyCustom(); | |||
} | |||
}, | |||
methods: { | |||
// 重置参数 | |||
resetRefreshParams() { | |||
this.timeText = '接待时间' | |||
this.activeTotal = 5 | |||
this.guwenText = '顾问' | |||
this.screen.agentId = '' // 顾问id | |||
this.steyStatus = '处理状态' | |||
this.orderBy = null | |||
this.weijinTag = '违禁标识' | |||
this.violatedStatus = null // 违禁状态 | |||
}, | |||
tapsoltishow() { | |||
this.soltishow = true; | |||
}, | |||
taptimeisshow() { | |||
this.timeshow = true; | |||
}, | |||
//选择标签 | |||
selectCallback2(e) { | |||
this.orderBy = e[0].value; | |||
this.steyStatus = e[0].label; | |||
this.nextPage = 1; | |||
this.recordList = []; | |||
this.isRefresh = false; | |||
this.getMyCustom(); | |||
}, | |||
// 选择违禁标识 | |||
selectIdent(e) { | |||
this.violatedStatus = e[0].value | |||
this.weijinTag = e[0].label | |||
this.nextPage = 1; | |||
this.recordList = []; | |||
this.isRefresh = false; | |||
this.getMyCustom(); | |||
}, | |||
//时间选择 | |||
tabtimetap(index, title) { | |||
this.timeshow = false; | |||
if (index == 4) { | |||
this.totalTimeShow = true; | |||
} else { | |||
this.timeText = title | |||
this.activeTotal = index; | |||
this.staTime = ''; | |||
this.endtime = ''; | |||
this.nextPage = 1; | |||
this.recordList = []; | |||
this.isRefresh = false; | |||
this.getMyCustom(); | |||
} | |||
}, | |||
//自定义时间 | |||
totalTimeChange(e) { | |||
this.staTime = e.startDate; | |||
this.endtime = e.endDate; | |||
this.timeText = `${e.startDate}-${e.endDate}` | |||
this.activeTotal = 4; | |||
this.nextPage = 1; | |||
this.recordList = []; | |||
this.isRefresh = false; | |||
this.getMyCustom(); | |||
}, | |||
// 跳转违禁详情 | |||
tapThevisiting(item, index) { | |||
if (item.status == 0) { | |||
uni.showToast({ | |||
icon: "none", | |||
title: "排队中" | |||
}) | |||
return | |||
} else { | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: item.id, | |||
} | |||
} | |||
this.$u.post("/customer/prohibitedMatch", { | |||
customerId: item.id | |||
}).then(res => { | |||
let newweijin = res[0]; | |||
newweijin.transferContent = JSON.parse(newweijin.transferContent) | |||
var item = { | |||
bg: newweijin.transferContent.bg, | |||
customerId: newweijin.corpusId, | |||
} | |||
uni.setStorageSync("searchobj", item); //写入缓存 | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
if (res == null) { | |||
uni.showToast({ | |||
icon: "none", | |||
title: "暂无音频" | |||
}) | |||
return | |||
} else { | |||
let newobj = res[0]; | |||
let obj = { | |||
pageSize: index+1, | |||
num: this.totalRecords, | |||
query: { | |||
...this.nextPageObj | |||
} | |||
} | |||
uni.setStorageSync('nextPageObj', JSON.stringify(obj)) | |||
uni.navigateTo({ | |||
url: `/pages/center/prohibited/details?customerId=${newobj.customerId}&status=${newobj.status}&stateisshow=${"2"}&index=${index}&isMerge=${res[0].merge}` | |||
}) | |||
// if (res[0].merge == 0) { | |||
// } | |||
// else { | |||
// uni.navigateTo({ | |||
// url: `/pages/mine/details?customerId=${newobj.customerId}&status=${newobj.status}&stateisshow=${"2"}` | |||
// }) | |||
// } | |||
} | |||
}) | |||
}) | |||
} | |||
}, | |||
// 获取围巾列表 | |||
getMyCustom() { | |||
let dateType = 0; | |||
if (this.activeTotal == 5) { | |||
dateType = null; | |||
} else if (this.activeTotal == 4) { | |||
dateType = null; | |||
} else { | |||
dateType = this.activeTotal; | |||
} | |||
var parames = { | |||
pageNum: this.nextPage, | |||
pageSize: 10, | |||
query: { | |||
projectId: this.buildingID, | |||
time: 1, | |||
staTime: this.staTime, | |||
endtime: this.endtime, | |||
taboo: 1, | |||
dateType: dateType, | |||
disposeStatus: this.orderBy, // 处理状态 | |||
violatedStatus: this.violatedStatus, // 违禁状态 | |||
} | |||
}; | |||
if (this.screen.agentId) { | |||
parames.query.agentId = this.screen.agentId | |||
} | |||
this.$u.post("/customer/findbypage", parames).then(data => { | |||
var list = data.results || []; | |||
if (this.isRefresh) { | |||
this.recordList = list; | |||
} else { | |||
this.recordList = [...this.recordList, ...list]; | |||
} | |||
this.totalRecord = data.totalPage; | |||
this.totalRecords = data.totalRecord; | |||
this.nextPageObj = parames.query | |||
}) | |||
}, | |||
//获取顾问列表 | |||
getFreeList() { | |||
this.$u.post("/cusLvStatistics/selectAllAccountIdByHouseId", { | |||
houseId: this.buildingID | |||
}).then(res => { | |||
this.freeList = res; | |||
this.freeList.forEach(item => { | |||
item.label = item.name; | |||
item.value = item.accountId | |||
}) | |||
this.freeList.unshift({ | |||
label: '全部', | |||
value: null, | |||
}) | |||
}) | |||
}, | |||
//顾问确认 | |||
actionSelectCallback(e) { | |||
this.screen.agentId = e[0].value; | |||
this.guwenText = e[0].label; | |||
this.recordList = []; | |||
this.nextPage = 1; | |||
this.selectshow = false; | |||
this.isRefresh = false; | |||
this.getMyCustom(); | |||
}, | |||
}, | |||
filters: { | |||
// violatedStatus | |||
ViolatedStatus(status) { | |||
let str = ''; | |||
switch (status) { | |||
case 0: | |||
str = '有效违禁' | |||
break; | |||
case 1: | |||
str = '有效违禁' | |||
break; | |||
case 2: | |||
str = '无效违禁' | |||
break; | |||
} | |||
return str | |||
}, | |||
// DisposeStatus | |||
DisposeStatus(status) { | |||
let str = ''; | |||
switch (status) { | |||
case 0: | |||
str = '待处理' | |||
break; | |||
case 1: | |||
str = '已处理' | |||
break; | |||
} | |||
return str | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100vw; | |||
min-height: calc(100vh - var(--window-top)); | |||
background: #F8F8F8; | |||
} | |||
.count { | |||
width: 100%; | |||
height: 90rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
background-color: #FBE4E4; | |||
text { | |||
color: #F71616; | |||
} | |||
} | |||
.timeview { | |||
height: 80rpx; | |||
line-height: 80rpx; | |||
width: 100%; | |||
text-align: center; | |||
border-bottom: 1px solid #F8F8F8; | |||
} | |||
//时间切换的样式 | |||
.boxtittab { | |||
position: sticky; | |||
top: var(--window-top); | |||
z-index: 100; | |||
width: 100; | |||
height: 92rpx; | |||
background: #FFFFFF; | |||
border: 1px solid #E0E0E0; | |||
display: flex; | |||
align-items: center; | |||
.tabbox { | |||
flex: 1; | |||
height: 100%; | |||
text-align: center; | |||
line-height: 92rpx; | |||
color: #666666; | |||
font-size: 28rpx; | |||
overflow: hidden; | |||
/* 超出一行文字自动隐藏 */ | |||
text-overflow: ellipsis; | |||
/*文字隐藏后添加省略号*/ | |||
white-space: nowrap; | |||
/*强制不换行*/ | |||
} | |||
} | |||
.search-box { | |||
width: 100%; | |||
height: 102rpx; | |||
background: #FFFFFF; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
.search { | |||
width: 94%; | |||
height: 70rpx; | |||
display: flex; | |||
align-items: center; | |||
background: #F8F8F8; | |||
border-radius: 33rpx; | |||
.search-img { | |||
width: 26rpx; | |||
height: 30rpx; | |||
margin-left: 20rpx; | |||
.search-img1 { | |||
width: 100%; | |||
height: 100%; | |||
margin-top: 2rpx; | |||
} | |||
} | |||
.search-text { | |||
font-size: 28rpx; | |||
font-weight: 400; | |||
color: #999999; | |||
margin-left: 10rpx; | |||
} | |||
} | |||
.search-screen { | |||
width: 40rpx; | |||
height: 40rpx; | |||
margin-left: 30rpx; | |||
.search-screen1 { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
} | |||
.content { | |||
.content-tips { | |||
margin: 0 0 20rpx 0; | |||
background: #fff; | |||
box-sizing: border-box; | |||
display: flex; | |||
flex-direction: column; | |||
.content-first { | |||
padding: 20rpx 30rpx; | |||
display: flex; | |||
justify-content: space-between; | |||
background-color: #EEF4FD; | |||
.left { | |||
display: flex; | |||
.img { | |||
margin-right: 10rpx; | |||
width: 52rpx; | |||
height: 52rpx; | |||
background: #FFFFFF; | |||
border: 1px solid #C9C9C9; | |||
border-radius: 50%; | |||
text-align: center; | |||
line-height: 52rpx; | |||
} | |||
.name { | |||
font-weight: 600; | |||
color: #333333; | |||
// margin-left: 20rpx; | |||
margin-top: 11rpx; | |||
} | |||
.status { | |||
width: 110rpx; | |||
height: 42rpx; | |||
background: #FFF9F5; | |||
border-radius: 4rpx; | |||
font-size: 26rpx; | |||
font-weight: 400; | |||
color: #EC8D49; | |||
line-height: 42rpx; | |||
text-align: center; | |||
margin-left: 19rpx; | |||
margin-top: 11rpx; | |||
} | |||
} | |||
.right { | |||
display: flex; | |||
margin-top: 11rpx; | |||
.point { | |||
width: 12rpx; | |||
height: 12rpx; | |||
background: #2B6EFF; | |||
border-radius: 50%; | |||
margin-right: 9rpx; | |||
margin-top: 16rpx; | |||
} | |||
} | |||
} | |||
.content-last { | |||
padding: 24rpx 30rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
display: flex; | |||
justify-content: space-between; | |||
.item { | |||
flex-shrink: 0; | |||
display: flex; | |||
align-items: center; | |||
image { | |||
margin-right: 10rpx; | |||
width: 32rpx; | |||
height: 32rpx; | |||
} | |||
text { | |||
font-size: 28rpx; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
// 这是弹出层 | |||
.screen { | |||
// box-sizing: border-box; | |||
// padding: 0 30rpx; | |||
position: absolute; | |||
.screen-counselor { | |||
display: flex; | |||
height: 106rpx; | |||
// padding: 40rpx 30rpx 36rpx 30rpx; | |||
padding: 0 30rpx; | |||
box-sizing: border-box; | |||
border-bottom: 1px solid #EEEEEE; | |||
.screen-text { | |||
margin: 40rpx 0 36rpx 0; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
line-height: 30rpx; | |||
} | |||
.screen-sel { | |||
display: flex; | |||
justify-content: space-between; | |||
width: 500rpx; | |||
margin-left: 60rpx; | |||
.screen-sel-img { | |||
margin: 40rpx 0 36rpx 0; | |||
width: 14rpx; | |||
height: 30rpx; | |||
} | |||
.screen-inp { | |||
margin-top: 20rpx; | |||
} | |||
} | |||
} | |||
.screen-record { | |||
height: 192rpx; | |||
// width: 100%; | |||
overflow: hidden; | |||
padding: 0 30rpx; | |||
box-sizing: border-box; | |||
border-bottom: 1px solid #EEEEEE; | |||
.screen-record-text { | |||
margin-top: 36rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
line-height: 30rpx; | |||
} | |||
.screen-record-tab { | |||
margin-top: 30rpx; | |||
display: flex; | |||
// justify-content: space-around; | |||
.screen-record-chose { | |||
width: 156rpx; | |||
height: 60rpx; | |||
background: #2671E2; | |||
border-radius: 4rpx; | |||
border: 1px solid #2671E2; | |||
text-align: center; | |||
line-height: 60rpx; | |||
margin-right: 22rpx; | |||
color: #FFFFFF; | |||
} | |||
.screen-record-nochose { | |||
width: 156rpx; | |||
height: 60rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #C9C9C9; | |||
text-align: center; | |||
line-height: 60rpx; | |||
margin-right: 22rpx; | |||
} | |||
} | |||
} | |||
.screen-foot { | |||
width: 100%; | |||
height: 100rpx; | |||
display: flex; | |||
.screen-foot-reset { | |||
width: 50%; | |||
text-align: center; | |||
height: 100rpx; | |||
line-height: 100rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
} | |||
.screen-foot-sure { | |||
width: 50%; | |||
text-align: center; | |||
line-height: 100rpx; | |||
height: 100rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #FFFFFF; | |||
background: #2671E2; | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,275 @@ | |||
<template> | |||
<view class="box"> | |||
<view style="width: 690rpx;margin: 0 auto;margin-top: 20rpx;"> | |||
<u-search @search='searchinfo()' :show-action='false' placeholder="请输入" v-model="keyword"></u-search> | |||
</view> | |||
<!-- <view @click="searchinfo()">搜索</view> --> | |||
<view class="content" style="background: #F8F8F8;"> | |||
<view class="content-tips" v-for="(item,index) in recordList" :key='index' @click="tapThevisiting(item)"> | |||
<view class="content-first"> | |||
<view class="left"> | |||
<!-- <view class="img">{{item.agentName.slice(0,1)}}</view> --> | |||
<view class="name">{{item.agentName}}</view> | |||
<view class="status" v-if="item.replaceReception==1">代接待</view> | |||
<view style="margin-left: 6rpx;margin-top: 11rpx;">{{item.receptionStatusName || ''}}</view> | |||
</view> | |||
<view class="right" v-if="item.recording!=0"> | |||
<view style="margin-right: 6rpx;">{{item.validInvalidName||''}}</view> | |||
<view v-if="methodsisshow==true"> | |||
<text style="color: red;" v-if="item.taboo==1">违禁接待</text> | |||
<text v-if="item.taboo==1"> |</text> | |||
</view> | |||
<!-- <view class="point"></view> --> | |||
<view v-if="item.markAdvisor==0" class="">未标记</view> | |||
<view v-if="item.markAdvisor==1" class="">已标记</view> | |||
</view> | |||
<view class="right" v-else> | |||
<view class="">无录音</view> | |||
</view> | |||
</view> | |||
<view class="content-sec"> | |||
<view class="left"> | |||
<view class="cus">客户:{{item.name || '--'}} |</view> | |||
<view class="arriveNum">{{item.visitRecord || "0"}}次到访</view> | |||
</view> | |||
<view class="right"> | |||
{{item.fraction || '0'}}% | |||
<!-- | {{item.fraction || '0'}}分 --> | |||
</view> | |||
</view> | |||
<view class="content-last"> | |||
{{item.createTime}} | {{item.mm || '0'}}分钟 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
export default{ | |||
data(){ | |||
return{ | |||
keyword:'', | |||
recordList:[], | |||
buildingID:'', | |||
nextPage:1, | |||
totalRecord:"", | |||
methodsisshow:false, | |||
userInfo:{} | |||
} | |||
}, | |||
onShow() { | |||
this.userInfo = uni.getStorageSync('weapp_session_userInfo_data'); | |||
if(this.userInfo.dataCode==6 || this.userInfo.dataCode==3){ | |||
this.methodsisshow=false; | |||
}else{ | |||
this.methodsisshow=true; | |||
} | |||
this.buildingID = uni.getStorageSync('buildingID').id; | |||
this.nextPage=1; | |||
this.recordList=[]; | |||
}, | |||
onReachBottom() { | |||
if(this.totalRecord==this.nextPage){ | |||
uni.showToast({ | |||
icon:'none', | |||
title: '到底了', | |||
duration: 2000 | |||
}); | |||
return | |||
}else{ | |||
this.nextPage+=1; | |||
this.getMyCustom(); | |||
} | |||
}, | |||
methods:{ | |||
tapThevisiting(item) { | |||
console.log("11111111111111") | |||
uni.showLoading({ | |||
title: '加载中', | |||
mask:true | |||
}); | |||
if(item.status==0){ | |||
setTimeout(function () { | |||
uni.hideLoading(); | |||
}, 2000); | |||
uni.showToast({ | |||
icon: "none", | |||
title: "排队中" | |||
}) | |||
return | |||
}else{ | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: item.id, | |||
} | |||
} | |||
var item={ | |||
bg:0, | |||
customerId:item.id, | |||
} | |||
uni.setStorageSync("entrance", 1); //写入缓存 | |||
uni.setStorageSync("searchobj", item); //写入缓存 | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
if(res==null){ | |||
setTimeout(function () { | |||
uni.hideLoading(); | |||
}, 2000); | |||
uni.showToast({ | |||
icon: "none", | |||
title: "暂无音频" | |||
}) | |||
return | |||
}else{ | |||
setTimeout(function () { | |||
uni.hideLoading(); | |||
}, 2000); | |||
let newobj = res[0]; | |||
if(res[0].merge==0){ | |||
uni.navigateTo({ | |||
url: `/pages/mine/details2?customerId=${newobj.customerId}&status=${newobj.status}&stateisshow=${"2"}` | |||
}) | |||
}else{ | |||
uni.navigateTo({ | |||
url: `/pages/mine/details?customerId=${newobj.customerId}&status=${newobj.status}&stateisshow=${"1"}` | |||
}) | |||
} | |||
} | |||
}) | |||
} | |||
}, | |||
searchinfo(){ | |||
this.nextPage=1; | |||
this.recordList=[]; | |||
this.getMyCustom(); | |||
}, | |||
getMyCustom(){ | |||
var parames = { | |||
pageNum: this.nextPage, | |||
pageSize: 10, | |||
query: { | |||
projectId:this.buildingID, | |||
time:1, | |||
nameOrPhone:this.keyword | |||
} | |||
}; | |||
this.$u.post("/customer/findbypage", parames).then(data => { | |||
var list = data.results || []; | |||
this.recordList = [...this.recordList, ...list]; | |||
this.totalRecord=data.totalPage; | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100%; | |||
height: 100vh; | |||
background: #FFFFFF; | |||
} | |||
.content{ | |||
.content-tips{ | |||
background: #fff; | |||
padding: 0 20rpx; | |||
box-sizing: border-box; | |||
overflow: hidden; | |||
margin-top: 20rpx; | |||
.content-first{ | |||
margin-top: 19rpx; | |||
display: flex; | |||
justify-content: space-between; | |||
.left{ | |||
display: flex; | |||
.img{ | |||
width: 52rpx; | |||
height: 52rpx; | |||
background: #FFFFFF; | |||
border: 1px solid #C9C9C9; | |||
border-radius: 50%; | |||
text-align: center; | |||
line-height: 52rpx; | |||
} | |||
.name{ | |||
font-weight: 600; | |||
color: #333333; | |||
// margin-left: 20rpx; | |||
margin-top: 11rpx; | |||
} | |||
.status{ | |||
width: 110rpx; | |||
height: 42rpx; | |||
background: #FFF9F5; | |||
border-radius: 4rpx; | |||
font-size: 26rpx; | |||
font-weight: 400; | |||
color: #EC8D49; | |||
line-height: 42rpx; | |||
text-align: center; | |||
margin-left: 19rpx; | |||
margin-top: 11rpx; | |||
} | |||
} | |||
.right{ | |||
display: flex; | |||
margin-top: 11rpx; | |||
.point{ | |||
width: 12rpx; | |||
height: 12rpx; | |||
background: #2B6EFF; | |||
border-radius: 50%; | |||
margin-right: 9rpx; | |||
margin-top: 16rpx; | |||
} | |||
} | |||
} | |||
.content-sec{ | |||
display: flex; | |||
justify-content: space-between; | |||
margin-top: 19rpx; | |||
.left{ | |||
display: flex; | |||
.cus{ | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
line-height: 30rpx; | |||
} | |||
.arriveNum{ | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
line-height: 30rpx; | |||
margin-left: 10rpx; | |||
} | |||
} | |||
.right{ | |||
width: 120rpx; | |||
height: 46rpx; | |||
background: #F4F8FD; | |||
border-radius: 6rpx; | |||
text-align: center; | |||
line-height: 46rpx; | |||
font-weight: 400; | |||
color: #2671E2; | |||
} | |||
} | |||
.content-last{ | |||
margin: 30rpx 0; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
line-height: 30rpx; | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,453 @@ | |||
<template> | |||
<view class="cented-box"> | |||
<view v-if="waitCustomList.length==0" style="width: 100%;height: 100%;display: flex;align-items: center;"> | |||
<view style="width: 100%;padding-top: 200rpx;"> | |||
<view style="width: 100%;text-align: center;"> | |||
<image style="width: 220rpx;height: 200rpx;" | |||
src="https://static.quhouse.com/zhikong_xcx_img/nodatalist.png" mode=""></image> | |||
</view> | |||
<view style="text-align: center;width: 100%;margin-top: 20rpx;color: #999999;">暂无数据</view> | |||
</view> | |||
</view> | |||
<view class="customer" v-if="waitCustomList.length!=0" v-for="(item,index) in waitCustomList" :key='index' | |||
@click="tapThevisiting(item)"> | |||
<view class="title"> | |||
<view class="zuo"> | |||
<!-- <view class="zuoimg">A</view> --> | |||
<view class="zuoname">{{item.name}}</view> | |||
</view> | |||
<view class="you"> | |||
<view class="youimg1" v-if="item.status!=0"></view> | |||
<view class="youimg1-1" v-if="item.status==0"></view> | |||
<view class="youtext">{{item.status==0?"排队中":item.status==1?"接待中":"已完成"}}</view> | |||
</view> | |||
</view> | |||
<view class="centerbox" v-if="item.status!=0"> | |||
<view class="centerbox-che">手机号码:<text class="shizai">{{item.phone || "--"}}</text></view> | |||
<view class="centerbox-che">开始时间:<text class="shizai">{{item.createTime}}</text></view> | |||
<view class="centerbox-che">顾问姓名:<text class="shizai" style="color: #333333;">{{item.agentName}}</text> | |||
</view> | |||
<view class="centerbox-che2" v-if="item.status==1"> | |||
<view class="Workcard" v-if="item.status==1&&item.zkEquipmentState.onLine==0">设备状态:<text | |||
class="shizai" style="color: red;">离线</text></view> | |||
<view class="Workcard" v-if="item.status==1&&item.zkEquipmentState.onLine!=0">工牌电量:<text | |||
class="shizai" style="color: #333333;">{{item.zkEquipmentState.electricity}}%</text></view> | |||
<view class="Workcard" v-if="item.status==1&&item.zkEquipmentState.onLine==1">录音状态: | |||
<text v-if="item.zkEquipmentState.audioStatus=='true'" class="shizai" | |||
style="color: #333333;">使用中</text> | |||
<text v-if="item.zkEquipmentState.audioStatus=='false'" class="shizai" | |||
style="color: #333333;">未使用</text> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="footer-button" v-if="item.status!=0"> | |||
<view class="footer1" @click.stop="addTime(item)">接待延时</view> | |||
<view class="footer1" @click.stop="assign(item)">重新指派</view> | |||
<template v-if="endReception"> | |||
<view class="footer3" @click.stop="changeEnd(item.id)">结束接待</view> | |||
</template> | |||
</view> | |||
<view class="centerbox" v-if="item.status==0"> | |||
<view class="centerbox-che">手机号码:<text class="shizai">{{item.phone || "--"}}</text></view> | |||
</view> | |||
<view class="footer-button" v-if="item.status==0"> | |||
<view class="footer3" @click.stop="assign(item)">指派顾问</view> | |||
</view> | |||
</view> | |||
<image v-if="isAdd == 0 && (dataCode!=6||(dataCode==6&&addAccount==0))" @click="addreception()" class="add" | |||
src="/static/images/add.png" mode=""></image> | |||
<image class="add2" @click="reshCustom()" src="https://static.quhouse.com/zhikong_xcx_img/refresh.png" mode=""> | |||
</image> | |||
<u-tabbar activeColor="#1296db" inactiveColor="#999999" v-model="current" :list="tabbarList"></u-tabbar> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
import tabbarList from '@/utils/tabbar.js' | |||
export default { | |||
data() { | |||
return { | |||
noClick:true, | |||
tabbarList:tabbarList, | |||
current: 0, | |||
buildingID: '', | |||
waitCustomList: [], | |||
isAdd: '', | |||
dataCode: '', | |||
addAccount: '', | |||
endReception: true, | |||
fdFlag:null | |||
}; | |||
}, | |||
components: {}, | |||
onLoad() {}, | |||
onShow() { | |||
this.buildingID = uni.getStorageSync('buildingID').id; | |||
const { | |||
addAccount, | |||
dataCode | |||
} = uni.getStorageSync("weapp_session_userInfo_data"); | |||
let menulist = uni.getStorageSync('weapp_session_Menu_data') | |||
this.endReception = menulist.findIndex(item => { return item.name == '结束接待' }) != -1 | |||
this.addAccount = addAccount; | |||
this.dataCode = dataCode; | |||
console.log(this.menulist) | |||
this.init() | |||
this.queryHaveDept() | |||
this.updateInit() | |||
}, | |||
methods: { | |||
updateInit() { | |||
uni.request({ | |||
url: config.service.notReadNum, | |||
method: "GET", | |||
data: { | |||
id: uni.getStorageSync('weapp_session_userInfo_data').accountId, | |||
projectId: uni.getStorageSync('buildingID').id, | |||
}, | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (res) => { | |||
this.count = res.data.data | |||
this.tabbarList[3].count = res.data.data || 0 | |||
} | |||
}) | |||
}, | |||
reshCustom() { | |||
this.init() | |||
}, | |||
tapThevisiting(item) { | |||
uni.showLoading({ | |||
title: '加载中', | |||
mask: true | |||
}); | |||
if (item.status == 0) { | |||
setTimeout(function() { | |||
uni.hideLoading(); | |||
}, 2000); | |||
uni.showToast({ | |||
icon: "none", | |||
title: "排队中" | |||
}) | |||
return | |||
} else { | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: item.id, | |||
} | |||
} | |||
var itemsd = { | |||
bg: 0, | |||
customerId: item.id, | |||
id: '', | |||
onebest: '' | |||
} | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
setTimeout(function() { | |||
uni.hideLoading(); | |||
}, 2000); | |||
if (res) { | |||
let newobj = res[0]; | |||
uni.navigateTo({ | |||
url: `/pages/mine/details?customerId=${newobj.customerId}&status=${newobj.status}&itemobj=${JSON.stringify(itemsd)}&stateisshow=${"1"}` | |||
}) | |||
} else { | |||
uni.showToast({ | |||
icon: "none", | |||
title: "暂无音频" | |||
}) | |||
return | |||
} | |||
}) | |||
} | |||
}, | |||
queryHaveDept() { | |||
return new Promise((resolve, reject) => { | |||
this.$u.get("/user/queryHaveDept?houseId=" + this.buildingID).then(res => { | |||
this.isAdd = res; | |||
resolve(); | |||
}) | |||
}) | |||
}, | |||
init() { | |||
this.waitCustomList = [] | |||
let parames = { | |||
itemId: this.buildingID | |||
} | |||
this.$u.post("/customer/reception", parames).then(data => { | |||
this.waitCustomList = data; | |||
}); | |||
}, | |||
//延时接待 | |||
addTime(item) { | |||
uni.showModal({ | |||
content: "确定延长半小时接待时间?", | |||
cancelColor: "#999999", | |||
success: res => { | |||
if (res.confirm) { | |||
this.$u.post("/customer/delayed", { | |||
cusId: item.id | |||
}).then(res => { | |||
uni.showToast({ | |||
icon: "none", | |||
title: "操作成功" | |||
}) | |||
}); | |||
} | |||
} | |||
}) | |||
}, | |||
//结束接待 | |||
changeEnd(id) { | |||
uni.showModal({ | |||
content: "确定更改当前客户接待状态为结束?", | |||
cancelColor: "#999999", | |||
success: res => { | |||
if (this.noClick) { | |||
this.noClick= false; | |||
if (res.confirm) { | |||
if (res.confirm) { | |||
this.$u.post("/customer/endReception", { | |||
id: id, | |||
houseId: this.buildingID | |||
}).then(res => { | |||
uni.showToast({ | |||
icon: "none", | |||
title: "操作成功" | |||
}) | |||
this.init(); | |||
}); | |||
} | |||
} | |||
setTimeout(()=> { | |||
this.noClick= true; | |||
}, 2000) | |||
} else { | |||
// 这里是重复点击的判断 | |||
} | |||
} | |||
}) | |||
}, | |||
//新增接待 | |||
addreception() { | |||
const { | |||
dataCode, | |||
addAccount | |||
} = uni.getStorageSync("weapp_session_userInfo_data"); | |||
if (dataCode == 6) { | |||
if (addAccount != 0) { | |||
uni.showToast({ | |||
title: '不允许自建客户!', | |||
duration: 2000 | |||
}); | |||
return | |||
} | |||
if (this.waitCustomList.length == 0) { | |||
uni.navigateTo({ | |||
url: '/pages/mine/reception/addreception' | |||
}) | |||
return | |||
} else { | |||
for (var i = 0; i < this.waitCustomList.length; i++) { | |||
if (this.waitCustomList[i].status == 1) { | |||
uni.showLoading({ | |||
title: '当前还有未完成的客户项' | |||
}); | |||
setTimeout(function() { | |||
uni.hideLoading(); | |||
}, 1000); | |||
return | |||
} else { | |||
uni.navigateTo({ | |||
url: '/pages/mine/reception/addreception' | |||
}) | |||
return | |||
} | |||
} | |||
} | |||
} else { | |||
uni.navigateTo({ | |||
url: '/pages/mine/reception/addreception' | |||
}); | |||
} | |||
}, | |||
assign(item) { | |||
let url = `/pages/mine/reception/consultant?id=${item.id}` | |||
if (item.beforeAgentId) { | |||
url += `&beforeAgentId=${item.beforeAgentId}`; | |||
} | |||
uni.navigateTo({ | |||
url: url | |||
}) | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.cented-box { | |||
background: #F8F8F8; | |||
width: 100%; | |||
height: 100vh; | |||
padding-bottom: 30rpx; | |||
} | |||
.customer { | |||
margin-top: 30rpx; | |||
width: 100%; | |||
background: #FFFFFF; | |||
box-shadow: 0px 0px 12px 0px rgba(224, 224, 224, 0.3); | |||
.title { | |||
height: 90rpx; | |||
border-bottom: 1px solid #E0E0E0; | |||
display: flex; | |||
align-items: center; | |||
.zuo { | |||
width: 80%; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
.zuoimg { | |||
width: 52rpx; | |||
height: 52rpx; | |||
border-radius: 50%; | |||
border: 1px solid #C9C9C9; | |||
font-size: 30rpx; | |||
color: #292929; | |||
font-weight: 400; | |||
line-height: 52rpx; | |||
text-align: center; | |||
margin-left: 30rpx; | |||
} | |||
.zuoname { | |||
font-size: 30rpx; | |||
font-weight: 500; | |||
color: #333333; | |||
line-height: 30rpx; | |||
margin-left: 20rpx; | |||
} | |||
} | |||
.you { | |||
width: 20%; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
.youimg1 { | |||
width: 12rpx; | |||
height: 12rpx; | |||
border-radius: 50%; | |||
background: #2B6EFF; | |||
} | |||
.youimg1-1 { | |||
width: 12rpx; | |||
height: 12rpx; | |||
border-radius: 50%; | |||
background: #F2A269; | |||
} | |||
.youtext { | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #292929; | |||
line-height: 30rpx; | |||
margin-left: 10rpx; | |||
} | |||
} | |||
} | |||
.centerbox { | |||
.centerbox-che { | |||
width: 100%; | |||
margin-top: 30rpx; | |||
height: 30rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
line-height: 30rpx; | |||
text-indent: 30rpx; | |||
.shizai { | |||
color: #333333; | |||
} | |||
} | |||
.centerbox-che2 { | |||
width: 100%; | |||
margin-top: 30rpx; | |||
height: 30rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #666666; | |||
line-height: 30rpx; | |||
text-indent: 30rpx; | |||
display: flex; | |||
.Workcard { | |||
width: 50%; | |||
} | |||
} | |||
} | |||
.footer-button { | |||
margin-top: 30rpx; | |||
width: 100%; | |||
height: 90rpx; | |||
display: flex; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
border-top: 1rpx solid #E0E0E0; | |||
.footer1 { | |||
flex: 1; | |||
text-align: center; | |||
line-height: 90rpx; | |||
border-right: 1rpx solid #E0E0E0; | |||
} | |||
.footer3 { | |||
flex: 1; | |||
text-align: center; | |||
line-height: 90rpx; | |||
} | |||
} | |||
} | |||
.add { | |||
width: 90upx; | |||
height: 90upx; | |||
position: fixed; | |||
bottom:275upx; | |||
right: 44upx; | |||
} | |||
.add2 { | |||
width: 90upx; | |||
height: 90upx; | |||
position: fixed; | |||
bottom: 160upx; | |||
right: 44upx; | |||
} | |||
</style> |
@@ -0,0 +1,182 @@ | |||
<template> | |||
<view class="boox"> | |||
<view class="title"> | |||
数智工牌 | |||
</view> | |||
<view class="booximg"> | |||
<!-- <image class="img" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/guidepage.png" mode=""></image> --> | |||
<image class="img" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images1.png" mode=""></image> | |||
</view> | |||
<view class="center-dingwei"> | |||
<view style="height: 44rpx;display: flex;margin-left: 213rpx;"> | |||
<image style="width: 44rpx;height: 44rpx;" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png" mode=""></image> | |||
<view style="line-height: 44rpx;margin-left: 10rpx;font-size: 32rpx;color: #333333;">智能语音转写</view> | |||
</view> | |||
<view style="height: 44rpx;display: flex;margin-left: 213rpx;margin-top: 20rpx;"> | |||
<image style="width: 44rpx;height: 44rpx;" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png" mode=""></image> | |||
<view style="line-height: 44rpx;margin-left: 10rpx;font-size: 32rpx;color: #333333;">高效的判客机制</view> | |||
</view> | |||
<view style="height: 44rpx;display: flex;margin-left: 213rpx;margin-top: 20rpx;"> | |||
<image style="width: 44rpx;height: 44rpx;" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png" mode=""></image> | |||
<view style="line-height: 44rpx;margin-left: 10rpx;font-size: 32rpx;color: #333333;">全方位的客户跟进</view> | |||
</view> | |||
<view style="height: 44rpx;display: flex;margin-left: 213rpx;margin-top: 20rpx;"> | |||
<image style="width: 44rpx;height: 44rpx;" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png" mode=""></image> | |||
<view style="line-height: 44rpx;margin-left: 10rpx;font-size: 32rpx;color: #333333;">专业的经济管家</view> | |||
</view> | |||
<view style="height: 44rpx;display: flex;margin-left: 213rpx;margin-top: 20rpx;"> | |||
<image style="width: 44rpx;height: 44rpx;" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png" mode=""></image> | |||
<view style="line-height: 44rpx;margin-left: 10rpx;font-size: 32rpx;color: #333333;">在线实时沟通</view> | |||
</view> | |||
</view> | |||
<view @click="bindWxBLogin" class="button"> | |||
<view class="view"> | |||
立即去登录 | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var app = getApp(); | |||
var config = require("../../config"); | |||
export default { | |||
data() { | |||
return { | |||
name:"", | |||
path:'/pages/index/index', | |||
pathurl:'/pages/index/index', | |||
pathur2:'/pages/index/customer', | |||
pathur3:'/pages/center/prohibited/index', | |||
}; | |||
}, | |||
onLoad(opts) { | |||
this.name=opts.loginName ||''; | |||
let stat=opts.path||''; | |||
if(stat==1){ | |||
this.path=this.pathur3; | |||
}else if(stat==2){ | |||
this.path=this.pathur2; | |||
}else{ | |||
this.path=this.pathurl; | |||
} | |||
}, | |||
onShow: function() { | |||
if(this.name==''){ | |||
uni.request({ | |||
url: config.service.verify, | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
if (data.data.code == 10000) { | |||
uni.switchTab({ | |||
url: '/pages/index/index' | |||
}); | |||
} | |||
} | |||
}) | |||
}else{ | |||
var userInfo=uni.getStorageSync('weapp_session_userInfo_data'); | |||
if(userInfo){ | |||
console.log(userInfo.loginName) | |||
if(this.name==userInfo.loginName){ | |||
uni.request({ | |||
url: config.service.verify, | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
if (data.data.code == 10000) { | |||
if(this.path=='/pages/center/prohibited/index'){ | |||
uni.navigateTo({ | |||
url:this.path | |||
}); | |||
}else{ | |||
uni.switchTab({ | |||
url:this.path | |||
}); | |||
} | |||
} | |||
} | |||
}) | |||
}else{ | |||
console.log("不是本人") | |||
} | |||
}else{ | |||
console.log("没有用户信息") | |||
} | |||
} | |||
}, | |||
methods: { | |||
bindWxBLogin() { | |||
wx.navigateTo({ | |||
url: '/pages/login/index' | |||
}); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.boox{ | |||
width: 100vw; | |||
height: 100vh; | |||
position: relative; | |||
.title { | |||
width: 100%; | |||
position: absolute; | |||
left: 0rpx; | |||
top: 100rpx; | |||
text-align: center; | |||
color: #FFFFFF; | |||
font-size: 32rpx; | |||
font-weight: 500; | |||
z-index: 1000; | |||
} | |||
.booximg{ | |||
width: 100vw; | |||
height: 96vh; | |||
.img{ | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
.center-dingwei{ | |||
width: 100%; | |||
position: absolute; | |||
left: 0rpx; | |||
bottom:230rpx; | |||
} | |||
.button { | |||
width: 100%; | |||
position: absolute; | |||
left: 0rpx; | |||
bottom:80rpx; | |||
.view{ | |||
width: 630rpx; | |||
height: 86rpx; | |||
margin: 0 auto; | |||
background: #2671E2; | |||
box-shadow: 0px 2rpx 20rpx 0rpx rgba(38, 113, 226, 0.5); | |||
border-radius: 49rpx; | |||
color: #FFFFFF; | |||
text-align: center; | |||
line-height: 86rpx; | |||
font-size: 32rpx; | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,626 @@ | |||
<template> | |||
<view class="main"> | |||
<view class="tab-box"> | |||
<view class="tab-item-wrap"> | |||
<view v-for="(item, index) in tablist" :key="index" | |||
:class="activeClass == index ? 'bottom' : ''" @click="clocktab(index, item.id)"> | |||
{{ item.name }} | |||
<view class="bottomLine" v-if="activeClass == index"></view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="cented" v-if="activeClass==0"> | |||
<view class="ceninfo" v-for="(item,index) in alllist" @click="quclick(item)" :key="index"> | |||
<view class="infoview"> | |||
<view class="infozuo"> | |||
<view class="infozuochiud1">{{item.jbaName}}</view> | |||
<view class="infozuochiud2">置业顾问</view> | |||
</view> | |||
<view class="infoyou"> | |||
<view class="infoyouchiud2" >去学习</view> | |||
</view> | |||
</view> | |||
<view class="footerinfo"> | |||
<view class="footerinfozuo">{{item.assignedTime}}</view> | |||
<view class="footerinfoyou"></view> | |||
</view> | |||
<view class="footicon"> | |||
<view class="icon"> | |||
<image class="Piabodata-img1" src="../../static/images/studyhot.png" mode=""></image> | |||
<!-- 浏览量 --> | |||
{{item.pageviews}} | |||
</view> | |||
<view class="icon"> | |||
<image class="Piabodata-img1" src="../../static/images/viewstudy.png" mode=""></image> | |||
<!-- 热度 --> | |||
{{item.heat}} | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="biaoqianview" v-if="activeClass==1"> | |||
<view class="boxintention"> | |||
<view class="title">分点标签列表</view> | |||
<view class="boxcenten" v-for="(item,index) in equinoctial" :key="index" @click="routerclick(item)"> | |||
<view class="boxcenteninfotext">{{item.name}}</view> | |||
<view class="boxcenteninfoimg"><u-icon size="20px" name="arrow-right"></u-icon></view> | |||
</view> | |||
</view> | |||
</view> | |||
<u-tabbar activeColor="#1296db" inactiveColor="#999999" v-model="current" :list="tabbarList"></u-tabbar> | |||
</view> | |||
</template> | |||
<script> | |||
var config = require("../../config"); | |||
var util = require("@/utils/util.js"); | |||
import tabbarList from '@/utils/tabbar.js' | |||
export default { | |||
data() { | |||
return { | |||
tabbarList:tabbarList, | |||
current: 0, | |||
tablist:[ | |||
{name:"全文"}, | |||
{name:"分点"} | |||
], | |||
activeClass:0, | |||
equinoctial:[], | |||
alllist:[], | |||
buildingID:'' | |||
}; | |||
}, | |||
onShow(){ | |||
var i=uni.getStorageSync('fendianindex') | |||
this.buildingID=uni.getStorageSync('buildingID').id; | |||
this.clocktab(i) | |||
this.updateInit() | |||
}, | |||
onPullDownRefresh() { | |||
var i=uni.getStorageSync('fendianindex') | |||
this.clocktab(i) | |||
setTimeout(function () { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
methods: { | |||
updateInit() { | |||
uni.request({ | |||
url: config.service.notReadNum, | |||
method: "GET", | |||
data: { | |||
id: uni.getStorageSync('weapp_session_userInfo_data').accountId, | |||
projectId: uni.getStorageSync('buildingID').id, | |||
}, | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (res) => { | |||
this.count = res.data.data | |||
this.tabbarList[3].count = res.data.data || 0 | |||
} | |||
}) | |||
}, | |||
//全部学习跳转 | |||
quclick(item){ | |||
uni.showLoading({ | |||
title: '加载中', | |||
mask:true | |||
}); | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: item.carId, | |||
} | |||
} | |||
var cet={ | |||
bg:0, | |||
customerId:item.id, | |||
id:'' | |||
} | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
setTimeout(function () { | |||
uni.hideLoading(); | |||
}, 2000); | |||
var newobj = res[0]; | |||
if(res[0].merge==0){ | |||
uni.navigateTo({ | |||
url: `/pages/learning/Thefulltext/index2?customerId=${newobj.customerId}&status=${newobj.status}&itemobj=${JSON.stringify(cet)}&stateisshow=${"2"}` | |||
}) | |||
}else{ | |||
uni.navigateTo({ | |||
url: `/pages/learning/Thefulltext/index?customerId=${newobj.customerId}` | |||
}) | |||
} | |||
}) | |||
}, | |||
//分点学习跳转 | |||
routerclick(item){ | |||
uni.navigateTo({ | |||
url: "/pages/learning/Equinoctiallearning?id="+item.marketingId+"&biaoqian="+item.name | |||
}) | |||
}, | |||
// tab切换 | |||
clocktab(index) { | |||
this.activeClass = index; | |||
if(this.activeClass==0){ | |||
uni.setStorageSync("fendianindex", 0); //写入缓存 | |||
this.ceninit() | |||
}else{ | |||
uni.setStorageSync("fendianindex", 1); //写入缓存 | |||
this.infoinit() | |||
} | |||
}, | |||
ceninit(){ | |||
let infoobj={ | |||
"pageNum":1, | |||
"pageSize":100, | |||
"query":{ | |||
"status":0, | |||
'itemId':this.buildingID, | |||
} | |||
} | |||
uni.request({ | |||
url: config.service.findAllZATD, | |||
method:"POST", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
data:infoobj, | |||
success: (data) => { | |||
if(data.data.code==10000){ | |||
this.alllist=data.data.data.results | |||
}else{ | |||
uni.showToast({ | |||
title: data.data.message, | |||
duration: 2000 | |||
}); | |||
} | |||
} | |||
}) | |||
}, | |||
infoinit(){ | |||
let obj={ | |||
itemId:this.buildingID | |||
} | |||
uni.request({ | |||
url: config.service.findSelectedLabel, | |||
method:"POST", | |||
data:obj, | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
if(data.data.code==10000){ | |||
this.equinoctial=data.data.data | |||
}else{ | |||
uni.showToast({ | |||
title: data.data.message, | |||
duration: 2000 | |||
}); | |||
} | |||
} | |||
}) | |||
} | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.main { | |||
background: #F1F1F1;; | |||
min-height: 100vh; | |||
} | |||
.tab-box { | |||
height: auto; | |||
overflow: auto; | |||
width: 100%; | |||
.tab-item-wrap { | |||
height: 100rpx; | |||
width: 80%; | |||
margin: 0 auto; | |||
line-height: 100rpx; | |||
display: flex; | |||
justify-content: space-around; | |||
font-size: 36rpx; | |||
color: #959dad; | |||
} | |||
} | |||
.bottom { | |||
color: #008EF2; | |||
position: relative; | |||
} | |||
.bottomLine { | |||
position: absolute; | |||
width: 96rpx; | |||
height: 6rpx; | |||
top: 80rpx; | |||
background-color: #298dff; | |||
border-radius: 8rpx 8rpx 0rpx 0rpx; | |||
left: -13rpx; | |||
} | |||
.cented{ | |||
width: 100%; | |||
padding-top: 14rpx; | |||
.ceninfo{ | |||
width: 690rpx; | |||
// height: 160rpx; | |||
background: #FFFFFF; | |||
border-radius: 8rpx; | |||
margin: 0 auto; | |||
margin-top: 20rpx; | |||
padding-top: 23rpx; | |||
position: relative; | |||
.infoview{ | |||
width: 100%; | |||
height: 64rpx; | |||
display: flex; | |||
.infozuo{ | |||
width: 454rpx; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
.infozuochiud1{ | |||
font-size: 36rpx; | |||
font-weight: 600; | |||
color: #0C0C0C; | |||
text-indent: 28rpx; | |||
} | |||
.infozuochiud2{ | |||
width: 113rpx; | |||
height: 42rpx; | |||
border-radius: 5rpx; | |||
margin-left: 19rpx; | |||
border: 1px solid #008EF2; | |||
font-size: 24rpx; | |||
font-weight: 400; | |||
color: #008EF2; | |||
line-height: 42rpx; | |||
text-align: center; | |||
} | |||
} | |||
.infoyou{ | |||
width:236rpx; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
.infoyouchiud1{ | |||
display: block; | |||
width: 64rpx; | |||
height: 64rpx; | |||
border-radius: 50%; | |||
} | |||
.infoyouchiud2{ | |||
width: 133rpx; | |||
height: 56rpx; | |||
background: #008EF2; | |||
border-radius: 8rpx; | |||
text-align: center; | |||
color: #FFFFFF; | |||
font-size: 30rpx; | |||
line-height: 56rpx; | |||
margin-left: 80rpx; | |||
} | |||
} | |||
} | |||
.footerinfo{ | |||
width: 100%; | |||
height: 42rpx; | |||
display: flex; | |||
margin-top: 14rpx; | |||
.footerinfozuo{ | |||
width: 454rpx; | |||
font-size: 30rpx; | |||
color: #0C0C0C; | |||
line-height: 42rpx; | |||
margin-left: 26rpx; | |||
} | |||
.footerinfoyou{ | |||
width: 236rpx; | |||
font-size: 24rpx; | |||
color: #999999; | |||
line-height: 42rpx; | |||
text-indent: 42rpx; | |||
} | |||
} | |||
.dingwei{ | |||
width: 100%; | |||
height: 60rpx; | |||
border: 1px solid red; | |||
position: absolute; | |||
top: 160rpx; | |||
left: 0rpx; | |||
} | |||
} | |||
} | |||
.biaoqianview{ | |||
width: 100%; | |||
.boxintention { | |||
width: 690rpx; | |||
margin: 0 auto; | |||
.title { | |||
font-size: 36upx; | |||
color: #333333; | |||
position: relative; | |||
display: flex; | |||
align-items: center; | |||
padding-left: 19upx; | |||
&:before { | |||
content: ''; | |||
position: absolute; | |||
left: 0; | |||
height: 30upx; | |||
width: 9upx; | |||
background: #008ef2; | |||
border-radius: 5rpx; | |||
} | |||
} | |||
.boxcenten{ | |||
width: 100%; | |||
height: 100rpx; | |||
background: #FFFFFF; | |||
border-radius: 8rpx; | |||
margin-top: 22rpx; | |||
display: flex; | |||
.boxcenteninfotext{ | |||
width: 90%; | |||
height: 100%; | |||
text-indent: 20rpx; | |||
line-height: 100rpx; | |||
font-size: 30rpx; | |||
color: #0C0C0C; | |||
} | |||
.boxcenteninfoimg{ | |||
width: 10%; | |||
height: 100%; | |||
line-height: 100rpx; | |||
} | |||
} | |||
} | |||
} | |||
.footicon{ | |||
display: flex; | |||
align-items: center; | |||
margin-top: 30rpx; | |||
padding:20rpx; | |||
flex-direction: row-reverse; | |||
.icon{ | |||
margin-left: 20rpx; | |||
} | |||
image{ | |||
width: 36rpx; | |||
height: 36rpx; | |||
margin-right: 20rpx; | |||
vertical-align: -7rpx; | |||
} | |||
} | |||
</style> | |||
<!-- <template> | |||
<view class="cented-box"> | |||
<view class="search-box"> | |||
<view class="search"> | |||
<view class="search-img"> | |||
<image class="search-img1" src="../../static/images/search.png" mode=""></image> | |||
</view> | |||
<view class="search-text">输入话术关键字</view> | |||
</view> | |||
</view> | |||
<view class="caseid-box"> | |||
<view class="caseid"> | |||
<image class="caseid-img1" src="../../static/images/good.png" mode=""></image> | |||
<view class="caseid-text">优秀案例</view> | |||
</view> | |||
<view class="caseid"> | |||
<image class="caseid-img1" src="../../static/images/problem.png" mode=""></image> | |||
<view class="caseid-text">问题库</view> | |||
</view> | |||
<view class="caseid"> | |||
<image class="caseid-img1" src="../../static/images/reverse.png" mode=""></image> | |||
<view class="caseid-text">反面案例</view> | |||
</view> | |||
</view> | |||
<view class="Pinspeak">销讲话术</view> | |||
<view class="chented"> | |||
<view class="title"> | |||
<view class="title1"></view> | |||
<view class="titletext">逼单话术</view> | |||
<view class="titleimg"> | |||
<image class="titleimg1" src="../../static/images/arrow.png" mode=""></image> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="chented"> | |||
<view class="title" style="border: none;"> | |||
<view class="title1"></view> | |||
<view class="titletext">品牌介绍</view> | |||
</view> | |||
<view class="chented-for"> | |||
<view class="chented-che">2021销售额</view> | |||
<view class="chented-che">2021销售额</view> | |||
<view class="chented-che">2021销售额</view> | |||
<view class="chented-che">2021销售额</view> | |||
</view> | |||
</view> | |||
<view class="chented"> | |||
<view class="title" style="border: none;"> | |||
<view class="title1"></view> | |||
<view class="titletext">品牌介绍</view> | |||
</view> | |||
<view class="chented-for"> | |||
<view class="chented-che">2021销售额</view> | |||
<view class="chented-che">2021销售额</view> | |||
<view class="chented-che">2021销售额</view> | |||
<view class="chented-che">2021销售额</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return {}; | |||
}, | |||
components: {}, | |||
onLoad() {}, | |||
onShow() {}, | |||
methods: { | |||
}, | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.cented-box{ | |||
background: #F8F8F8; | |||
width: 100%; | |||
height: 100%; | |||
} | |||
.search-box{ | |||
width: 100%; | |||
height: 102rpx; | |||
background: #FFFFFF; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
.search{ | |||
width: 690rpx; | |||
height: 70rpx; | |||
display: flex; | |||
align-items: center; | |||
background: #F8F8F8; | |||
border-radius: 33rpx; | |||
.search-img{ | |||
width: 26rpx; | |||
height: 30rpx; | |||
margin-left: 20rpx; | |||
.search-img1{ | |||
width: 100%; | |||
height: 100%; | |||
margin-top: 2rpx; | |||
} | |||
} | |||
.search-text{ | |||
font-size: 28rpx; | |||
font-weight: 400; | |||
color: #999999; | |||
margin-left:10rpx; | |||
} | |||
} | |||
} | |||
.caseid-box{ | |||
width: 100%; | |||
height: 204rpx; | |||
margin-top: 10rpx; | |||
background: #FFFFFF; | |||
display: flex; | |||
.caseid{ | |||
flex: 1; | |||
height: 100%; | |||
text-align: center; | |||
margin-top: 13rpx; | |||
.caseid-img1{ | |||
width: 134rpx; | |||
height: 134rpx; | |||
} | |||
.caseid-text{ | |||
width: 100%; | |||
text-align: center; | |||
font-size: 24rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
} | |||
} | |||
} | |||
.Pinspeak{ | |||
width: 100%; | |||
height: 92rpx; | |||
border-bottom: 1rpx solid #E0E0E0; | |||
font-size: 32rpx; | |||
font-weight: 600; | |||
color: #333333; | |||
text-indent: 30rpx; | |||
line-height: 92rpx; | |||
background: #FFFFFF; | |||
margin-top: 20rpx; | |||
} | |||
.chented{ | |||
width: 100%; | |||
padding-left: 30rpx; | |||
padding-right: 30rpx; | |||
background-color: #FFFFFF; | |||
.title{ | |||
width: 100%; | |||
height: 90rpx; | |||
border-bottom: 1rpx solid #E0E0E0; | |||
display: flex; | |||
align-items: center; | |||
.title1{ | |||
width: 6rpx; | |||
height: 30rpx; | |||
background: #2671E2; | |||
} | |||
.titletext{ | |||
width: 90%; | |||
height: 30rpx; | |||
font-size: 30rpx; | |||
font-weight: 600; | |||
color: #333333; | |||
line-height: 30rpx; | |||
text-indent: 10rpx; | |||
} | |||
.titleimg{ | |||
width: 8%; | |||
text-align: right; | |||
.titleimg1{ | |||
width: 14rpx; | |||
height: 30rpx; | |||
} | |||
} | |||
} | |||
.chented-for{ | |||
width: 100%; | |||
display: flex; | |||
flex-wrap: wrap; | |||
margin-top: -20rpx; | |||
border-bottom: 1rpx solid #E0E0E0; | |||
padding-bottom: 30rpx; | |||
.chented-che{ | |||
width: 210rpx; | |||
height: 60rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #C9C9C9; | |||
text-align: center; | |||
line-height: 60rpx; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
margin-right: 20rpx; | |||
margin-top: 20rpx; | |||
} | |||
} | |||
} | |||
</style> | |||
--> |
@@ -0,0 +1,305 @@ | |||
<template> | |||
<view class="main"> | |||
<view class="backTop"></view> | |||
<!-- 头部开始 --> | |||
<view class="header box"> | |||
<view class="header-zuo"> | |||
<u-avatar | |||
:src="photo?photo:'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/zkgj/headPicture.png'" | |||
size="148"></u-avatar> | |||
</view> | |||
<view class="header-you"> | |||
<view class="userName">{{name}}</view> | |||
<view class="mobile">{{mobile}}</view> | |||
</view> | |||
</view> | |||
<view class="settingGroup box"> | |||
<navigator class="line" url="/pages/mine/messageList"> | |||
<view class="title" style="width: 21%;"> | |||
<image src="/static/images/studyhot.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
消息 | |||
</view> | |||
<view class="right" style="display: flex;align-items: center;"> | |||
<view class="count" v-if="count!=0">{{count}}</view> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</navigator> | |||
<navigator class="line" url="/pages/mine/subscribe"> | |||
<view class="title"> | |||
<image src="/static/images/studyhot.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
订阅消息 | |||
</view> | |||
<view class="right"> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</navigator> | |||
<navigator class="line" url="/pages/mine/Myprofile"> | |||
<view class="title"> | |||
<image src="/static/images/setting.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
编辑资料 | |||
</view> | |||
<view class="right"> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</navigator> | |||
<view class="line" @click="phone"> | |||
<view class="title"> | |||
<image src="/static/images/Customer.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
客服电话 | |||
</view> | |||
<view class="right"> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="line" @click="scan"> | |||
<view class="title" style="width: 220rpx;"> | |||
<image src="/static/images/reg.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
访客登记码 | |||
</view> | |||
<view class="right"> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="line" @click="Changehepassword"> | |||
<view class="title"> | |||
<image src="/static/images/password.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
修改密码 | |||
</view> | |||
<view class="right"> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</view> | |||
<view class="line" @click="logout" style="border: none;"> | |||
<view class="title"> | |||
<image src="/static/images/exit.png" style="width: 36rpx;height: 36rpx;" mode=""></image> | |||
退出登录 | |||
</view> | |||
<view class="right"> | |||
<image src="/static/images/arrow.png" style="width: 18rpx;height: 32rpx;" mode=""></image> | |||
</view> | |||
</view> | |||
</view> | |||
<u-tabbar activeColor="#1296db" inactiveColor="#999999" v-model="current" :list="tabbarList"></u-tabbar> | |||
</view> | |||
</template> | |||
<script> | |||
var app = getApp(); | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
import tabbarList from '@/utils/tabbar.js' | |||
export default { | |||
data() { | |||
return { | |||
tabbarList:tabbarList, | |||
current: 0, | |||
tabList: [ | |||
{ | |||
name: '系统消息' | |||
}, | |||
{ | |||
name: '升级公告' | |||
}, | |||
], | |||
name: "", | |||
photo: "", | |||
mobile: "", | |||
count:0, | |||
}; | |||
}, | |||
onShow: function() { | |||
var userInfos = uni.getStorageSync('weapp_session_userInfo_data'); | |||
this.name = userInfos.name, | |||
this.photo = userInfos.picUrl, | |||
this.mobile = userInfos.loginName | |||
this.updateInit() | |||
}, | |||
methods: { | |||
updateInit() { | |||
uni.request({ | |||
url: config.service.notReadNum, | |||
method: "GET", | |||
data: { | |||
id: uni.getStorageSync('weapp_session_userInfo_data').accountId, | |||
projectId: uni.getStorageSync('buildingID').id, | |||
}, | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (res) => { | |||
this.count = res.data.data | |||
this.tabbarList[3].count = res.data.data || 0 | |||
} | |||
}) | |||
}, | |||
scan(){ | |||
uni.navigateTo({ | |||
url:"../mine/registerCode" | |||
}) | |||
}, | |||
//拨打电话 | |||
phone() { | |||
wx.makePhoneCall({ | |||
phoneNumber: '4008191707,8888' //仅为示例,并非真实的电话号码 | |||
}) | |||
}, | |||
//修改密码 | |||
Changehepassword() { | |||
uni.navigateTo({ | |||
url: '/pages/mine/Changehepassword' | |||
}); | |||
}, | |||
//退出 | |||
logout() { | |||
uni.showModal({ | |||
title: '提示', | |||
content: '确定要退出?', | |||
cancelColor: "#999999", | |||
showCancel: true, | |||
success(res) { | |||
if (res.confirm) { | |||
app.Closewebsocke() | |||
uni.clearStorageSync(); //清除缓存 | |||
uni.showToast({ | |||
icon: "none", | |||
title: "退出成功" | |||
}) | |||
uni.reLaunch({ | |||
url: '/pages/login/index' | |||
}); | |||
} | |||
} | |||
}); | |||
}, | |||
// tosubscr(){ | |||
// let that=this; | |||
// wx.login({ | |||
// success (res) { | |||
// if (res.code) { | |||
// let appid ='wxd9748307889cbe0d'; | |||
// let secret = 'cfc40d2b86b650e216e900a2c430cd2b' | |||
// let url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + appid + '&secret=' + secret + '&js_code=' +res.code + '&grant_type=authorization_code'; | |||
// uni.request({ | |||
// url: url, // 请求路径 | |||
// success: result => { | |||
// that.$u.get("/user/bindMessage",{ | |||
// openId:result.data.openid, | |||
// loginName:that.mobile | |||
// }).then(data => { | |||
// console.log(data) | |||
// }) | |||
// } | |||
// }) | |||
// } else { | |||
// console.log('登录失败!' + res.errMsg) | |||
// } | |||
// } | |||
// }) | |||
// // /pages/mine/subscribe | |||
// }, | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.count{ | |||
background: red; | |||
width: 50rpx; | |||
height: 50rpx; | |||
border-radius: 40rpx; | |||
color: #FFFFFF; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
font-size: 24rpx; | |||
margin-right: 20rpx; | |||
} | |||
.main { | |||
padding: 0 30rpx; | |||
background: #F8F8F8; | |||
display: flex; | |||
flex-direction: column; | |||
min-height: 100vh; | |||
padding-bottom: 40rpx; | |||
.backTop { | |||
background: #2671E2; | |||
position: absolute; | |||
left: 0; | |||
top: 0; | |||
width: 750rpx; | |||
height: 171rpx; | |||
} | |||
.box { | |||
background: #ffffff; | |||
} | |||
} | |||
.header { | |||
z-index: 2; | |||
width: 100%; | |||
height: 212rpx; | |||
border-radius: 12rpx; | |||
margin-top: 42rpx; | |||
display: flex; | |||
.header-zuo { | |||
width: 148rpx; | |||
height: 148rpx; | |||
margin-top: 32rpx; | |||
margin-left: 30rpx; | |||
} | |||
.header-you { | |||
margin-left: 20rpx; | |||
.userName { | |||
font-size: 36rpx; | |||
font-weight: 500; | |||
color: #303030; | |||
margin-top: 56rpx; | |||
} | |||
.mobile { | |||
font-size: 30rpx; | |||
color: #BDBDBD; | |||
margin-top: 20rpx; | |||
} | |||
} | |||
} | |||
.settingGroup { | |||
box-shadow: 0px 0px 12px 0px rgba(224, 224, 224, 0.3); | |||
border-radius: 12rpx; | |||
margin-top: 30rpx; | |||
color: #333333; | |||
font-size: 30rpx; | |||
display: flex; | |||
flex-direction: column; | |||
.line { | |||
height: 118rpx; | |||
border-bottom: 1rpx solid #EEEEEE; | |||
margin: 0 38rpx 0 30rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
.title { | |||
display: flex; | |||
align-items: center; | |||
width: 190rpx; | |||
justify-content: space-between; | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,237 @@ | |||
<template> | |||
<view class="main"> | |||
<view class="cented"> | |||
<view class="ceninfo" v-for="(item,index) in alllist" :key="index"> | |||
<view class="infoview"> | |||
<view class="infozuo"> | |||
<view class="infozuochiud1">{{item.jbaName}}</view> | |||
<view class="infozuochiud2">置业顾问</view> | |||
</view> | |||
<view class="infoyou"> | |||
<view class="infoyouchiud2" @click="quclick(item)">去学习</view> | |||
</view> | |||
</view> | |||
<view class="footerinfo"> | |||
<view class="footerinfozuo">{{item.assignedTime}}</view> | |||
<view class="footerinfoyou"></view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var config = require("../../config"); | |||
var util = require("../../utils/util.js"); | |||
export default { | |||
data() { | |||
return { | |||
alllist: [], | |||
id: "", | |||
biaoqian:"" | |||
}; | |||
}, | |||
onLoad(options) { | |||
this.id = options.id; | |||
this.biaoqian=options.biaoqian | |||
this.ceninit() | |||
}, | |||
onPullDownRefresh() { | |||
this.ceninit() | |||
setTimeout(function () { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
methods: { | |||
quclick(item) { | |||
uni.showLoading({ | |||
title: '加载中', | |||
mask:true | |||
}); | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
whetherFinish: 1, | |||
customerId: item.carId, | |||
id:item.startFile | |||
} | |||
} | |||
var cet={ | |||
bg:0, | |||
customerId:item.id, | |||
id:'' | |||
} | |||
this.$u.post("/corpus/fendianFindByPage", parames).then(res => { | |||
var newobj = res[0]; | |||
setTimeout(function () { | |||
uni.hideLoading(); | |||
}, 2000); | |||
if(res[0].merge==0){ | |||
uni.navigateTo({ | |||
url: `/pages/learning/Equinoctial/index2?customerId=${newobj.customerId}&biaoqian=${this.biaoqian}&startTime=${item.startTime}&startFile=${item.startFile}` | |||
}) | |||
}else{ | |||
uni.navigateTo({ | |||
url: `/pages/learning/Equinoctial/index?customerId=${newobj.customerId}&biaoqian=${this.biaoqian}&startTime=${item.startTime}&startFile=${item.startFile}` | |||
}) | |||
} | |||
}) | |||
}, | |||
ceninit() { | |||
let itemid=uni.getStorageSync('buildingID').id; | |||
let infoobj = { | |||
"pageNum": 1, | |||
"pageSize": 100, | |||
"query": { | |||
"status": 1, | |||
"marketingId": this.id, | |||
"itemId":itemid | |||
} | |||
} | |||
uni.request({ | |||
url: config.service.findAllZATD, | |||
method: "POST", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
data: infoobj, | |||
success: (data) => { | |||
console.log(data.data.data.results, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"); | |||
if (data.data.code == 10000) { | |||
this.alllist = data.data.data.results | |||
} else { | |||
uni.showToast({ | |||
title: data.data.message, | |||
duration: 2000 | |||
}); | |||
} | |||
} | |||
}) | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.main { | |||
background: #F1F1F1; | |||
; | |||
min-height: 100vh; | |||
padding-top: 30rpx; | |||
} | |||
.cented { | |||
width: 100%; | |||
padding-top: 14rpx; | |||
.ceninfo { | |||
width: 690rpx; | |||
height: 160rpx; | |||
background: #FFFFFF; | |||
border-radius: 8rpx; | |||
margin: 0 auto; | |||
padding-top: 23rpx; | |||
position: relative; | |||
margin-top: 20rpx; | |||
.infoview { | |||
width: 100%; | |||
height: 64rpx; | |||
display: flex; | |||
.infozuo { | |||
width: 454rpx; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
.infozuochiud1 { | |||
font-size: 36rpx; | |||
font-weight: 600; | |||
color: #0C0C0C; | |||
text-indent: 28rpx; | |||
} | |||
.infozuochiud2 { | |||
width: 113rpx; | |||
height: 42rpx; | |||
border-radius: 5rpx; | |||
margin-left: 19rpx; | |||
border: 1px solid #008EF2; | |||
font-size: 24rpx; | |||
font-weight: 400; | |||
color: #008EF2; | |||
line-height: 42rpx; | |||
text-align: center; | |||
} | |||
} | |||
.infoyou { | |||
width: 236rpx; | |||
height: 100%; | |||
display: flex; | |||
align-items: center; | |||
.infoyouchiud1 { | |||
display: block; | |||
width: 64rpx; | |||
height: 64rpx; | |||
border-radius: 50%; | |||
} | |||
.infoyouchiud2 { | |||
width: 133rpx; | |||
height: 56rpx; | |||
background: #008EF2; | |||
border-radius: 8rpx; | |||
text-align: center; | |||
color: #FFFFFF; | |||
font-size: 30rpx; | |||
line-height: 56rpx; | |||
margin-left: 80rpx; | |||
} | |||
} | |||
} | |||
.footerinfo { | |||
width: 100%; | |||
height: 42rpx; | |||
display: flex; | |||
margin-top: 14rpx; | |||
.footerinfozuo { | |||
width: 454rpx; | |||
font-size: 30rpx; | |||
color: #0C0C0C; | |||
line-height: 42rpx; | |||
margin-left: 26rpx; | |||
} | |||
.footerinfoyou { | |||
width: 236rpx; | |||
font-size: 24rpx; | |||
color: #999999; | |||
line-height: 42rpx; | |||
text-indent: 42rpx; | |||
} | |||
} | |||
.dingwei { | |||
width: 100%; | |||
height: 60rpx; | |||
border: 1px solid red; | |||
position: absolute; | |||
top: 160rpx; | |||
left: 0rpx; | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,146 @@ | |||
<template> | |||
<view class="translation"> | |||
<view style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;background: #F2F2F2;border-radius: 32rpx; | |||
display: flex;align-items: center;"> | |||
<view style="width: 10%;height: 64rpx;display: flex;align-items: center;"> | |||
<image style="width: 28rpx;height: 28rpx;margin-left: 30rpx;" src="/static/images/search.png" mode=""></image> | |||
</view> | |||
<view style="width: 90%;height: 64rpx;display: flex;align-items: center;"> | |||
<input type="text" @input="searchinfo" :disabled="disabled" v-model="keyword" placeholder="请输入关键字" | |||
style="width: 100%;color: #999999;font-size: 24rpx;"/> | |||
</view> | |||
</view> | |||
<view style="width: 690rpx;margin: 0 auto;margin-top: 10rpx;"> | |||
<view style="width: 100%;border-bottom: 1px solid #E0E0E0;display: flex;padding-bottom: 10rpx;margin-top: 40rpx;" | |||
v-for="(item,index) in listarr" :key='index' @click="toaidoinfo(item.Content,item.corpusId,item.index)"> | |||
<view style="width: 26rpx;height: 36rpx;margin-top: 4rpx;"> | |||
<image style="width: 26rpx;height: 28rpx;" src="../../static/images/testimg.png" mode=""></image> | |||
</view> | |||
<view v-html="item.Content.text" style="color: #666666;font-size: 28rpx;line-height: 36rpx;margin-left: 10rpx;width: 80%;"></view> | |||
<view style="font-size: 28rpx;width: 10%;width: 14%;text-align: right;">{{item.Content.time}}</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
export default { | |||
data() { | |||
return { | |||
customerId:'', | |||
listarr:[], | |||
keyword:'', | |||
skpl:'', | |||
disabled:false, | |||
tipsFncName: '', // 通知其他页面的方法名称 | |||
}; | |||
}, | |||
onLoad(options) { | |||
this.customerId = options.customerId; | |||
this.keyword=options.keyword; | |||
this.skpl=options.skpl; | |||
if (options.UpDateEvent) this.tipsFncName = options.UpDateEvent | |||
if(this.skpl==2){ | |||
this.searchinfo() | |||
this.disabled=true; | |||
}else{ | |||
this.disabled=false; | |||
} | |||
}, | |||
methods: { | |||
formatTime(num) { | |||
//格式化时间格式 | |||
num = num.toFixed(0); | |||
let second = num % 60; | |||
if (second < 10) second = '0' + second; | |||
let min = Math.floor(num / 60); | |||
if (min < 10) min = '0' + min; | |||
return min + ":" + second; | |||
}, | |||
searchinfo(){ | |||
if(this.keyword.length==0){ | |||
return | |||
}else{ | |||
let parames={ | |||
keyword:this.keyword, | |||
customerId:this.customerId | |||
} | |||
this.$u.post("/corpus/keyWordsMatching", parames).then(res => { | |||
res.forEach(item=>{ | |||
item.Content=JSON.parse(item.transferContent) | |||
}) | |||
res.forEach(cet=>{ | |||
cet.Content.time=this.formatTime(cet.Content.bg/1000) | |||
cet.Content.text=this.brightKeyword(cet.Content.onebest) | |||
}) | |||
this.listarr=res; | |||
}) | |||
} | |||
}, | |||
//替换方法 | |||
brightKeyword(val) { | |||
if (val.indexOf(this.keyword) !== -1) { | |||
return val.replace(this.keyword, `<font style='color: red'>${this.keyword}</font>`); | |||
} else { | |||
return val; | |||
} | |||
}, | |||
//跳转 | |||
toaidoinfo(item,id,index){ | |||
uni.setStorageSync("entrance", 2); //写入缓存 | |||
item.customerId=this.customerId; | |||
item.id=id; | |||
item.index=index; | |||
if(this.skpl==2){ | |||
this.infostust(item) | |||
}else{ | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
if (this.tipsFncName) uni.$emit(this.tipsFncName, item) | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: item | |||
}); | |||
wx.navigateBack({ //然后返回上一个页面 | |||
delta: 1 | |||
}) | |||
} | |||
}, | |||
//只有一条的时候 | |||
infostust(item){ | |||
uni.setStorageSync("searchobj", item); //写入缓存 | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: this.customerId, | |||
} | |||
} | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
if(res[0].merge==0){ | |||
let newobj = res[0]; | |||
if (this.tipsFncName) { | |||
uni.$emit(this.tipsFncName, item) | |||
uni.navigateBack() | |||
return | |||
} | |||
uni.navigateTo({ | |||
url: `/pages/mine/details2?customerId=${newobj.customerId}&status=${newobj.status}&stateisshow=${'2'}` | |||
}) | |||
}else{ | |||
let newobj = res[0]; | |||
uni.navigateTo({ | |||
url: `/pages/mine/details?customerId=${newobj.customerId}&status=${newobj.status}&stateisshow=${'2'}` | |||
}) | |||
} | |||
}) | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
</style> |
@@ -0,0 +1,144 @@ | |||
<template> | |||
<view class="translation"> | |||
<view style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;background: #F2F2F2;border-radius: 32rpx; | |||
display: flex;align-items: center;"> | |||
<view style="width: 10%;height: 64rpx;display: flex;align-items: center;"> | |||
<image style="width: 28rpx;height: 28rpx;margin-left: 30rpx;" src="/static/images/search.png" mode=""></image> | |||
</view> | |||
<view style="width: 90%;height: 64rpx;display: flex;align-items: center;"> | |||
<input type="text" @input="searchinfo" :disabled="disabled" v-model="keyword" placeholder="请输入关键字" | |||
style="width: 100%;color: #999999;font-size: 24rpx;"/> | |||
</view> | |||
</view> | |||
<view style="width: 690rpx;margin: 0 auto;margin-top: 10rpx;"> | |||
<view style="width: 100%;border-bottom: 1px solid #E0E0E0;display: flex;padding-bottom: 10rpx;margin-top: 40rpx;" | |||
v-for="(item,index) in listarr" :key='index' @click="toaidoinfo(item.Content,item.corpusId,item.index)"> | |||
<view style="width: 26rpx;height: 36rpx;margin-top: 4rpx;"> | |||
<image style="width: 26rpx;height: 28rpx;" src="/static/images/testimg.png" mode=""></image> | |||
</view> | |||
<view v-html="item.Content.text" style="color: #666666;font-size: 28rpx;line-height: 36rpx;margin-left: 10rpx;width: 80%;"></view> | |||
<view style="font-size: 28rpx;width: 10%;width: 14%;text-align: right;">{{item.Content.time}}</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../../utils/util.js"); | |||
var config = require("../../../config"); | |||
export default { | |||
data() { | |||
return { | |||
customerId:'', | |||
listarr:[], | |||
keyword:'', | |||
skpl:'', | |||
disabled:false, | |||
tipsFncEvent: "", | |||
}; | |||
}, | |||
onLoad(options) { | |||
this.customerId = options.customerId; | |||
this.keyword=options.keyword; | |||
this.skpl=options.skpl; | |||
if (options.UpDateEvent) this.tipsFncEvent = options.UpDateEvent | |||
}, | |||
methods: { | |||
formatTime(num) { | |||
//格式化时间格式 | |||
num = num.toFixed(0); | |||
let second = num % 60; | |||
if (second < 10) second = '0' + second; | |||
let min = Math.floor(num / 60); | |||
if (min < 10) min = '0' + min; | |||
return min + ":" + second; | |||
}, | |||
searchinfo(){ | |||
if(this.keyword.length==0){ | |||
return | |||
}else{ | |||
let parames={ | |||
keyword:this.keyword, | |||
customerId:this.customerId | |||
} | |||
this.$u.post("/corpus/keyWordsMatching", parames).then(res => { | |||
res.forEach(item=>{ | |||
item.Content=JSON.parse(item.transferContent) | |||
}) | |||
res.forEach(cet=>{ | |||
cet.Content.time=this.formatTime(cet.Content.bg/1000) | |||
cet.Content.text=this.brightKeyword(cet.Content.onebest) | |||
}) | |||
this.listarr=res; | |||
}) | |||
} | |||
}, | |||
//替换方法 | |||
brightKeyword(val) { | |||
if (val.indexOf(this.keyword) !== -1) { | |||
return val.replace(this.keyword, `<font style='color: red'>${this.keyword}</font>`); | |||
} else { | |||
return val; | |||
} | |||
}, | |||
//跳转 | |||
toaidoinfo(item,id,index){ | |||
item.customerId=this.customerId; | |||
item.id=id; | |||
item.index=index; | |||
if(this.skpl==2){ | |||
this.infostust(item) | |||
}else{ | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
uni.$emit(this.tipsFncEvent, item) | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: item | |||
}); | |||
wx.navigateBack({ //然后返回上一个页面 | |||
delta: 1 | |||
}) | |||
} | |||
}, | |||
//只有一条的时候 | |||
infostust(item){ | |||
let d = JSON.parse(JSON.stringify([item])) | |||
var itemobjhh={ | |||
bg:d[0].bg, | |||
customerId:d[0].customerId, | |||
id:'', | |||
onebest:d[0].onebest, | |||
} | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: this.customerId, | |||
} | |||
} | |||
console.log(item) | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
if(res[0].merge==0){ | |||
let newobj = res[0]; | |||
uni.navigateTo({ | |||
url: `/pages/learning/Thefulltext/index2?customerId=${newobj.customerId}&status=${newobj.status}&itemobj=${JSON.stringify(itemobjhh)}&stateisshow=${'2'}` | |||
}) | |||
}else{ | |||
let newobj = res[0]; | |||
uni.navigateTo({ | |||
url: `/pages/learning/Thefulltext/index?customerId=${newobj.customerId}&status=${newobj.status}&itemobj=${JSON.stringify(itemobjhh)}&stateisshow=${'2'}` | |||
}) | |||
} | |||
}) | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
</style> |
@@ -0,0 +1,348 @@ | |||
<template> | |||
<view> | |||
<view style="width: 100%;height: 180rpx;"></view> | |||
<view class="input"> | |||
<view class="zcasfdasf">设置密码</view> | |||
<view class="tejHdgasd">设置密码后,就可以使用手机号码与密码登录了~</view> | |||
<view style="margin-top:60rpx" class="cwjs-cells item-flex"> | |||
<view class="cwjs-item center"> | |||
<input class="cwjs-item cwjs-input" v-model="username" password="true" placeholder="请设置6~12位的登录密码" | |||
placeholder-style='color:#AAAAAA' maxlength="12" /> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="button" @tap="bindWxBLogin">确认</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
var app = getApp(); | |||
var WXB_SESSION_LOGIN_DATA = 'weapp_session_login_data'; | |||
export default { | |||
data() { | |||
return { | |||
username: '', //获取到的密码 | |||
phone: '' | |||
} | |||
}, | |||
onLoad: function(options) { | |||
this.phone = options.username | |||
}, | |||
methods: { | |||
bindWxBLogin() { | |||
if (this.username.length < 6) { | |||
util.showNone("密码小于6位,请重试"); | |||
return false; | |||
} else { | |||
var loginParams = { | |||
name: this.phone, //手机号 | |||
newPassword: this.username, //密码 | |||
} | |||
uni.request({ | |||
url: config.service.forgotPassword, | |||
header: { | |||
'content-type': 'application/json' | |||
}, | |||
data: loginParams, | |||
method: "POST", | |||
success: function(result) { | |||
if (result.data.code == 10000) { | |||
uni.reLaunch({ | |||
url: '/pages/login/index', | |||
}) | |||
} else { | |||
util.showNone(result.data.message); | |||
return false; | |||
} | |||
} | |||
}) | |||
} | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.cwjs-logo { | |||
display: block; | |||
width: 219rpx; | |||
height: 158rpx; | |||
margin: 54rpx auto 66rpx; | |||
} | |||
.cwjs-tips { | |||
font-size: 24rpx; | |||
padding: 80rpx 0; | |||
color: #8a8a8a; | |||
} | |||
.cwjs-form { | |||
position: relative; | |||
margin: 0; | |||
background-color: #fff; | |||
border-radius: 10px; | |||
padding: 20rpx 40rpx 113rpx; | |||
} | |||
.zcasfdasf { | |||
height: 48rpx; | |||
font-size: 48rpx; | |||
font-weight: 400; | |||
color: #303030; | |||
line-height: 48rpx; | |||
margin-top: 80rpx; | |||
} | |||
.tejHdgasd { | |||
height: 28rpx; | |||
font-size: 26rpx; | |||
font-weight: 400; | |||
color: #303030; | |||
line-height: 28rpx; | |||
margin-top: 28rpx; | |||
} | |||
.cwjs-cells { | |||
width: 600rpx; | |||
display: flex; | |||
flex-direction: row; | |||
justify-content: space-between; | |||
align-items: center; | |||
margin: 0 auto; | |||
height: 88rpx; | |||
overflow: hidden; | |||
border-bottom: 1rpx solid #BFC7D3; | |||
position: relative; | |||
} | |||
.center { | |||
flex: 1; | |||
display: flex; | |||
} | |||
.texteasda { | |||
height: 88rpx; | |||
line-height: 88rpx; | |||
font-size: 28rpx; | |||
color: #000; | |||
} | |||
.cwjs-input { | |||
width: 100%; | |||
height: 88rpx; | |||
line-height: 88rpx; | |||
font-size: 28rpx; | |||
color: #000; | |||
} | |||
.images { | |||
display: block; | |||
width: 40rpx; | |||
height: 21rpx; | |||
margin-right: 30rpx; | |||
margin-top: 33.5rpx; | |||
} | |||
.mod-btn { | |||
position: absolute; | |||
bottom: -80rpx; | |||
left: 50%; | |||
margin-left: -80rpx; | |||
} | |||
.mod-btn .button { | |||
width: 160rpx; | |||
height: 160rpx; | |||
background: linear-gradient(180deg, rgba(116, 197, 230, 1) 0%, rgba(64, 147, 201, 1) 100%); | |||
border: 10rpx solid rgba(255, 255, 255, 1); | |||
border-radius: 100%; | |||
font-size: 36rpx; | |||
color: #fff; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
} | |||
.mod-btn .button::after { | |||
content: "" | |||
} | |||
.retPassword { | |||
display: inline; | |||
width: auto; | |||
font-size: 28rpx; | |||
color: rgba(64, 147, 201, 1); | |||
line-height: 40rpx; | |||
float: right; | |||
} | |||
.retPassword:active { | |||
background-color: #fff; | |||
} | |||
.appliyAdmin { | |||
position: absolute; | |||
left: 50%; | |||
margin-left: -57rpx; | |||
bottom: 100rpx; | |||
width: 114rpx; | |||
font-size: 28rpx; | |||
color: rgba(255, 255, 255, 1); | |||
line-height: 40rpx; | |||
} | |||
/* 头部 */ | |||
.head { | |||
width: 750rpx; | |||
height: 355rpx; | |||
} | |||
.background { | |||
width: 750rpx; | |||
height: 400rpx; | |||
position: absolute; | |||
top: -3rpx; | |||
left: 0; | |||
} | |||
.logo { | |||
width: 123rpx; | |||
height: 107rpx; | |||
display: block; | |||
position: absolute; | |||
top: 84rpx; | |||
left: 313.5rpx; | |||
} | |||
.head text { | |||
font-size: 34rpx; | |||
font-family: PingFangSC-Medium, PingFang SC; | |||
font-weight: 500; | |||
color: #2343BD; | |||
position: absolute; | |||
top: 222rpx; | |||
left: 203rpx; | |||
} | |||
/* 输入框 */ | |||
.input { | |||
width: 100%; | |||
height: auto; | |||
padding: 0 90rpx; | |||
box-sizing: border-box; | |||
} | |||
.logo_input { | |||
width: 34rpx; | |||
height: 38rpx; | |||
position: absolute; | |||
top: 25rpx; | |||
left: 0; | |||
} | |||
/* 登录 */ | |||
.button { | |||
width: 630rpx; | |||
height: 86rpx; | |||
background: #2671E2; | |||
box-shadow: 0px 2rpx 20rpx 0px rgba(38, 113, 226, 0.5); | |||
border-radius: 49rpx; | |||
text-align: center; | |||
line-height: 89rpx; | |||
color: #fff; | |||
margin: 0 auto; | |||
margin-top: 239rpx; | |||
font-size: 34rpx; | |||
} | |||
.footer { | |||
width: 100%; | |||
height: 157rpx; | |||
position: absolute; | |||
bottom: 0; | |||
left: 0; | |||
} | |||
.agreeBox { | |||
/* text-align: center; */ | |||
/* width: 450rpx; */ | |||
/* padding-left: 145rpx; */ | |||
font-size: 28rpx; | |||
color: #88909E; | |||
margin: 0 auto; | |||
margin-top: 30rpx; | |||
position: relative; | |||
display: flex; | |||
} | |||
checkbox { | |||
transform: scale(0.5); | |||
} | |||
checkbox-group { | |||
display: inline; | |||
} | |||
navigator { | |||
display: inline | |||
} | |||
.agreeBox image { | |||
width: 26rpx; | |||
height: 26rpx; | |||
display: block; | |||
position: absolute; | |||
top: 9rpx; | |||
left: 18rpx; | |||
margin-right: 19rpx; | |||
} | |||
.imagesBox { | |||
width: 80rpx; | |||
height: 88rpx; | |||
} | |||
.chooseBox { | |||
width: 60rpx; | |||
height: 60rpx; | |||
} | |||
.login { | |||
text-decoration: underline; | |||
text-align: center; | |||
margin-top: 40px; | |||
color: #88909E; | |||
font-size: 28rpx; | |||
} | |||
.textbox { | |||
width: 569rpx; | |||
display: flex; | |||
margin-top: 40rpx; | |||
} | |||
.textbox-1 { | |||
width: 30%; | |||
font-size: 30rpx; | |||
color: #999999; | |||
} | |||
.textbox-11 { | |||
width: 30%; | |||
text-align: right; | |||
font-size: 30rpx; | |||
color: #999999; | |||
} | |||
.textbox-2 { | |||
width: 40%; | |||
} | |||
</style> |
@@ -0,0 +1,250 @@ | |||
<template> | |||
<view> | |||
<view class="head"> | |||
<template v-if="role == 2"> | |||
<view class="phones">输入手机号</view> | |||
</template> | |||
<template v-else> | |||
<image class="head-immg" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/login.png" mode=""></image> | |||
</template> | |||
</view> | |||
<view class="input"> | |||
<view class="cwjs-cells item-flex"> | |||
<view class="cwjs-item center"> | |||
<input type="text" v-model="username" placeholder="请输入手机号码" maxlength="11" | |||
placeholder-style='color:#AAAAAA' /> | |||
</view> | |||
</view> | |||
<view class="textbox"> | |||
<view class="textbox-1" @tap="bindVerification">密码登录</view> | |||
<view class="textbox-2"></view> | |||
<view class="textbox-11"></view> | |||
</view> | |||
</view> | |||
<view class="button" @tap="bindWxBLogin">获取验证码</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
var app = getApp(); | |||
export default { | |||
data() { | |||
return { | |||
username: '', | |||
role: '' | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
this.role=options.role; | |||
}, | |||
methods: { | |||
//账号密码登录 | |||
bindVerification() { | |||
uni.navigateTo({ | |||
url: '/pages/login/index', | |||
}) | |||
}, | |||
//获取验证码 | |||
bindWxBLogin: function(e) { | |||
if (!(/^[1][3,4,5,7,8,9][0-9]{9}$/.test(this.username))) { | |||
util.showNone("手机号码错误"); | |||
this.username=''; | |||
return false; | |||
} else { | |||
uni.request({ | |||
url: config.service.sendCode + "?mobile=" + this.username, | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
console.log(data) | |||
// 成功地响应会话信息 | |||
if (data.data.code == 10000) { | |||
util.showSuccess('发送成功'); | |||
if(this.role==1){ | |||
uni.navigateTo({ | |||
url: '/pages/login/yinzhongmalogin?username=' + this.username + | |||
'&role=' + this.role, | |||
}) | |||
}else{ | |||
uni.navigateTo({ | |||
url: '/pages/login/Verifythelogin?username=' + this.username + | |||
'&role=' + this.role, | |||
}) | |||
} | |||
// 没有正确响应会话信息 | |||
} else { | |||
util.showNone(data.data.message); | |||
return false; | |||
} | |||
}, | |||
}) | |||
} | |||
}, | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.cwjs-logo { | |||
display: block; | |||
width: 219rpx; | |||
height: 158rpx; | |||
margin: 54rpx auto 66rpx; | |||
} | |||
.cwjs-tips { | |||
font-size: 24rpx; | |||
padding: 80rpx 0; | |||
color: #8a8a8a; | |||
} | |||
.cwjs-form { | |||
position: relative; | |||
margin: 0; | |||
background-color: #fff; | |||
border-radius: 10px; | |||
padding: 20rpx 40rpx 113rpx; | |||
} | |||
.cwjs-cells { | |||
width: 569rpx; | |||
display: flex; | |||
flex-direction: row; | |||
justify-content: space-between; | |||
align-items: center; | |||
margin: 0 auto; | |||
height: 88rpx; | |||
overflow: hidden; | |||
border-bottom: 1rpx solid #BFC7D3; | |||
position: relative; | |||
} | |||
.center { | |||
flex: 1; | |||
} | |||
.cwjs-input { | |||
height: 48rpx; | |||
line-height: 48rpx; | |||
padding: 23rpx 23rpx 23rpx 78rpx; | |||
font-size: 28rpx; | |||
font-family: PingFangSC-Regular, PingFang SC; | |||
color: #000; | |||
} | |||
.images { | |||
display: block; | |||
width: 40rpx; | |||
height: 21rpx; | |||
margin-right: 30rpx; | |||
margin-top: 33.5rpx; | |||
} | |||
/* 头部 */ | |||
.head { | |||
width: 750rpx; | |||
height: 500rpx; | |||
position: relative; | |||
.phones { | |||
position: absolute; | |||
top: 300rpx; | |||
left: 100rpx; | |||
color: #0A6EE9; | |||
font-size: 36rpx; | |||
font-weight: bold; | |||
} | |||
.head-immg { | |||
width: 118rpx; | |||
height: 61rpx; | |||
position: absolute; | |||
top: 300rpx; | |||
left: 100rpx; | |||
} | |||
} | |||
.logo { | |||
width: 248upx; | |||
height: 248upx; | |||
display: block; | |||
position: absolute; | |||
top: 134rpx; | |||
left: 240.5rpx; | |||
} | |||
/* 输入框 */ | |||
.input { | |||
width: 100%; | |||
height: auto; | |||
padding: 0 105rpx; | |||
box-sizing: border-box; | |||
} | |||
.logo_input { | |||
width: 34rpx; | |||
height: 38rpx; | |||
position: absolute; | |||
top: 25rpx; | |||
left: 0; | |||
} | |||
/* 登录 */ | |||
.button { | |||
width: 630rpx; | |||
height: 86rpx; | |||
background: #2671E2; | |||
box-shadow: 0px 2rpx 20rpx 0px rgba(38, 113, 226, 0.5); | |||
border-radius: 49rpx; | |||
text-align: center; | |||
line-height: 89rpx; | |||
color: #fff; | |||
margin: 0 auto; | |||
margin-top: 239rpx; | |||
font-size: 34rpx; | |||
} | |||
.login { | |||
text-decoration: underline; | |||
text-align: center; | |||
margin-top: 40px; | |||
color: #88909E; | |||
font-size: 28rpx; | |||
} | |||
.textbox { | |||
width: 569rpx; | |||
display: flex; | |||
margin-top: 40rpx; | |||
} | |||
.textbox-1 { | |||
width: 30%; | |||
font-size: 30rpx; | |||
color: #999999; | |||
} | |||
.textbox-11 { | |||
width: 30%; | |||
text-align: right; | |||
font-size: 30rpx; | |||
color: #999999; | |||
} | |||
.textbox-2 { | |||
width: 40%; | |||
} | |||
</style> |
@@ -0,0 +1,262 @@ | |||
<template> | |||
<view class="content"> | |||
<view class="head"> | |||
<view class="text"> | |||
<view class="text1"> | |||
<view style="color: #666666;">输入短信验证码</view> | |||
<view style="color: #303030;margin-top: 20rpx;">短信已发送至{{phone}},请在下方输入框内输入4位数字验证码</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="sction"> | |||
<view class="mama"> | |||
<view class="mamaz"> | |||
<input type="text" v-model="msg" maxlength="4" placeholder="请输入验证码" placeholder-class="input-class" class="input" /> | |||
</view> | |||
<view class="mamay"> | |||
<view class="sada" v-if="sendAuthCode" style="font-size: 35rpx;" @click="getAuthCode">获取验证码</view> | |||
<text class="sada" v-if="!sendAuthCode"> | |||
重新发送 | |||
<text>({{ auth_time }})</text> | |||
</text> | |||
</view> | |||
</view> | |||
<view class="login-btn" :style="{ background: msg == '' ? '#F2F2F2' : '#2671E2' }" @click="denglu"><text | |||
class="">确认</text></view> | |||
<view class="code-login" @click="passwordlogin"><text>密码登录</text></view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
var app = getApp(); | |||
export default { | |||
data() { | |||
return { | |||
sendAuthCode: true, | |||
auth_time: 0, | |||
msg: '', | |||
phonecet: '', | |||
role:'', | |||
phone:'' | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
var phonese = options.username; | |||
var phonexxz = phonese.substring(0, 3) + '****' + phonese.substring(7); | |||
this.phone = phonexxz, | |||
this.phonecet = options.username, | |||
this.role = options.role | |||
if (options.role == 2) { | |||
uni.setNavigationBarTitle({ | |||
title: '验证手机号' | |||
}) | |||
} | |||
this.sendAuthCode = false; | |||
this.auth_time = 60; | |||
var auth_timetimer = setInterval(() => { | |||
this.auth_time--; | |||
if (this.auth_time <= 0) { | |||
this.sendAuthCode = true; | |||
clearInterval(auth_timetimer); | |||
} | |||
}, 1000); | |||
}, | |||
methods: { | |||
//跳转密码登录页面 | |||
passwordlogin() { | |||
uni.reLaunch({ | |||
url: '/pages/login/index', | |||
}) | |||
}, | |||
//获取验证码 | |||
getAuthCode() { | |||
this.sendAuthCode = false; | |||
this.auth_time = 60; | |||
var auth_timetimer = setInterval(() => { | |||
this.auth_time--; | |||
if (this.auth_time <= 0) { | |||
this.sendAuthCode = true; | |||
clearInterval(auth_timetimer); | |||
} | |||
}, 1000); | |||
}, | |||
//登录 | |||
denglu() { | |||
if (this.msg=='') { | |||
uni.showToast({ | |||
title: '验证码不能为空', | |||
icon: 'none' | |||
}); | |||
return | |||
} | |||
if (this.msg.length == 4) { | |||
uni.navigateTo({ | |||
url: '/pages/login/Setthepassword?username='+this.phonecet, | |||
}) | |||
} else { | |||
uni.showToast({ | |||
title: '验证码位数不正确', | |||
icon: 'none' | |||
}); | |||
} | |||
}, | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.head { | |||
width: 750rpx; | |||
height:400rpx; | |||
position: relative; | |||
.text{ | |||
width: 100%; | |||
position: absolute; | |||
top: 180rpx; | |||
left: 0rpx; | |||
.text1{ | |||
width: 80%; | |||
margin: 0 auto; | |||
} | |||
} | |||
} | |||
.mama { | |||
width: 620rpx; | |||
display: flex; | |||
border-bottom: 1px solid #E1E1E1; | |||
margin: 60rpx auto; | |||
} | |||
.sadsadasdasdsadasd { | |||
font-size: 34rpx; | |||
font-family: PingFangSC-Medium, PingFang SC; | |||
font-weight: 500; | |||
color: #008EF2; | |||
width: 100%; | |||
text-align: center; | |||
padding-top: 340rpx; | |||
} | |||
.mamaz { | |||
width: 50%; | |||
height: 90rpx; | |||
} | |||
.mamay { | |||
width: 50%; | |||
height: 90rpx; | |||
} | |||
.input { | |||
width: 350rpx; | |||
color: #78DFB0; | |||
height: 100%; | |||
line-height: 90rpx; | |||
font-size: 17px; | |||
color: #171717; | |||
} | |||
.sada { | |||
width: 70%; | |||
line-height: 90rpx; | |||
color: #2B6EFF; | |||
text-align: right; | |||
font-size: 35rpx; | |||
margin-left: 100rpx; | |||
display: block; | |||
} | |||
.content { | |||
margin: 0; | |||
padding: 0; | |||
border-top: 1rpx solid #E0E0E0; | |||
} | |||
.login-text { | |||
font-size: 60rpx; | |||
font-family: PingFang SC; | |||
font-weight: 500; | |||
color: rgba(23, 23, 23, 1); | |||
letter-spacing: 8rpx; | |||
margin-left: 75rpx; | |||
font-weight: bold; | |||
} | |||
.login-input { | |||
border-bottom: 1px solid #e1e1e1; | |||
color: #c9cac9; | |||
margin: 98rpx 64rpx 200rpx 75rpx; | |||
font-size: 17px; | |||
} | |||
.login-btn { | |||
margin: 0 auto; | |||
margin-top: 240rpx; | |||
width: 630rpx; | |||
height: 86rpx; | |||
border-radius: 49rpx; | |||
font-size: 17px; | |||
font-weight: bold; | |||
border: none; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
color: #ffffff; | |||
} | |||
.code-login { | |||
display: flex; | |||
justify-content: center; | |||
margin-top: 40rpx; | |||
color: #D6D7D6; | |||
margin-bottom: 200rpx; | |||
font-size: 30rpx; | |||
} | |||
.log-box { | |||
display: flex; | |||
flex-direction: row; | |||
justify-content: center; | |||
align-items: center; | |||
font-size: 28rpx; | |||
color: #bfc0bf; | |||
margin-bottom: 65rpx; | |||
} | |||
.hengx { | |||
margin: 0 20rpx 0 20rpx; | |||
height: 2rpx; | |||
width: 232rpx; | |||
background: #e1e1e1; | |||
} | |||
.wechat { | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
width: 93rpx; | |||
height: 93rpx; | |||
background: rgba(255, 255, 255, 1); | |||
box-shadow: 0px 10rpx 30rpx rgba(120, 223, 176, 0.22); | |||
border-radius: 50%; | |||
margin: 0 auto; | |||
} | |||
.btn-get { | |||
width: 250rpx; | |||
font-size: 17px; | |||
color: #c9cac9; | |||
position: relative; | |||
top: -290rpx; | |||
right: -450rpx; | |||
} | |||
.input-class { | |||
color: #D6D7D6; | |||
font-size: 17px; | |||
letter-spacing: 1rpx; | |||
} | |||
</style> |
@@ -0,0 +1,324 @@ | |||
<template> | |||
<view> | |||
<view class="head"> | |||
<image class="head-immg" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/login.png" mode=""></image> | |||
</view> | |||
<view class="input"> | |||
<view class="cwjs-cells item-flex"> | |||
<view class="cwjs-item center"> | |||
<image src="https://qufang.oss-cn-beijing.aliyuncs.com/channelHelper/user.png" class="logo_input"> | |||
</image> | |||
<input class="cwjs-item cwjs-input" v-model="username" placeholder="请输入账号名" type="number" maxlength="11" placeholder-style="color:#AAAAAA"></input> | |||
</view> | |||
</view> | |||
<view class="cwjs-cells item-flex" style="margin-top:13rpx;"> | |||
<view class="cwjs-item center"> | |||
<image src="https://qufang.oss-cn-beijing.aliyuncs.com/channelHelper/lock.png" class="logo_input"> | |||
</image> | |||
<input class="cwjs-item cwjs-input" placeholder="请输入密码" placeholder-style="color:#AAAAAA" type="password" v-model="password" maxlength="16" v-if="passwordType"></input> | |||
<input class="cwjs-item cwjs-input" placeholder="请输入密码" placeholder-style="color:#AAAAAA" maxlength="16" v-model="password" v-else></input> | |||
</view> | |||
<view class="imagesBox" @tap="changeBindPassword"> | |||
<image v-if="passwordType==false" src="../../static/images/zhengkai.png" class="images" mode="scaleToFill"></image> | |||
<image v-if="passwordType==true" src="../../static/images/bishang.png" class="images" mode="scaleToFill"></image> | |||
</view> | |||
</view> | |||
<view class="textbox"> | |||
<view class="textbox-1" @tap="bindVerification">验证码登录</view> | |||
<view class="textbox-2"></view> | |||
<view class="textbox-11" @tap="bindpassword">忘记密码</view> | |||
</view> | |||
</view> | |||
<view class="button" @tap="bindWxBLogin">立即登录</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
var app = getApp(); | |||
var WXB_SESSION_LOGIN_DATA = 'weapp_session_login_data'; | |||
export default { | |||
data() { | |||
return { | |||
username: '', | |||
//获取到的用户名的值 | |||
password: '', | |||
//获取到的密码栏中的值 | |||
passwordType: true, | |||
agreeChecked: true | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
uni.hideToast(); | |||
}, | |||
methods: { | |||
//验证码登录 | |||
bindVerification() { | |||
uni.navigateTo({ | |||
url: '/pages/login/Verification?role=1', | |||
}) | |||
}, | |||
//忘记密码 | |||
bindpassword() { | |||
uni.navigateTo({ | |||
url: '/pages/login/Verification?role=2', | |||
}) | |||
}, | |||
//密码选择 | |||
changeBindPassword: function(e) { | |||
this.passwordType=!this.passwordType; | |||
}, | |||
//登录 | |||
bindWxBLogin: function(e) { | |||
util.showBusy('正在登录...'); | |||
var that = this; | |||
if (this.username == '') { | |||
util.showNone("请输入账号名"); | |||
return false; | |||
} | |||
if (this.password == '') { | |||
util.showNone("请输入密码"); | |||
return false; | |||
} | |||
var loginParams = { | |||
loginName: this.username, | |||
password: this.password | |||
}; | |||
// 请求服务器登录地址,获得会话信息 | |||
uni.request({ | |||
url: config.service.login, | |||
header: { | |||
'content-type': 'application/json' | |||
}, | |||
method: "POST", | |||
data: loginParams, | |||
success: function(result) { | |||
var data = result.data; //console.log("登陆信息", data); | |||
if (data && data.code == 10000) { | |||
var res = data.data; | |||
if (res) { | |||
var data = { | |||
'token': res | |||
}; | |||
uni.setStorageSync(WXB_SESSION_LOGIN_DATA, data); //写入缓存 | |||
that.getMenu() | |||
that.getUser(); | |||
util.showSuccess('登录成功'); | |||
} else { | |||
util.showNone("账号名或密码错误,请重试"); | |||
return false; | |||
} | |||
// 没有正确响应会话信息 | |||
} else { | |||
util.showNone(data.message); | |||
return false; | |||
} | |||
}, | |||
// 响应错误 | |||
fail: function(loginResponseError) { | |||
util.showNone("网络异常,请重试"); | |||
return false; | |||
} | |||
}); | |||
}, | |||
getUser(){ | |||
util.getRequestPromise(config.service.getUser, {}, false, "GET").then(data => { | |||
if (data.zkProperties) { | |||
} else { | |||
data.zkProperties = [{ | |||
id: "", | |||
propertyName: '' | |||
}] | |||
} | |||
let lopan = { | |||
id: data.zkProperties[0].id, | |||
name: data.zkProperties[0].propertyName | |||
} | |||
uni.setStorageSync("fendianindex", 0); //写入缓存 | |||
uni.setStorageSync("weapp_session_userInfo_data", data); //写入缓存 | |||
uni.setStorageSync("buildingID", lopan); //项目id写入缓存 | |||
uni.switchTab({ | |||
url: '/pages/index/index' | |||
}); | |||
}); | |||
}, | |||
getMenu(){ | |||
this.$u.get("/user/getMenu").then(data => { | |||
uni.setStorageSync("weapp_session_Menu_data", data) | |||
}) | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.cwjs-logo { | |||
display: block; | |||
width: 219rpx; | |||
height: 158rpx; | |||
margin: 54rpx auto 66rpx; | |||
} | |||
.cwjs-tips { | |||
font-size: 24rpx; | |||
padding: 80rpx 0; | |||
color: #8a8a8a; | |||
} | |||
.cwjs-form { | |||
position: relative; | |||
margin: 0; | |||
background-color: #fff; | |||
border-radius: 10px; | |||
padding: 20rpx 40rpx 113rpx; | |||
} | |||
.cwjs-cells { | |||
width: 569rpx; | |||
display: flex; | |||
flex-direction: row; | |||
justify-content: space-between; | |||
align-items: center; | |||
margin: 0 auto; | |||
height: 88rpx; | |||
overflow: hidden; | |||
border-bottom: 1rpx solid #BFC7D3; | |||
position: relative; | |||
} | |||
.center { | |||
flex: 1; | |||
} | |||
.cwjs-input { | |||
height: 48rpx; | |||
line-height: 48rpx; | |||
padding: 23rpx 23rpx 23rpx 78rpx; | |||
font-size: 28rpx; | |||
font-family: PingFangSC-Regular, PingFang SC; | |||
color: #000; | |||
} | |||
.images { | |||
display: block; | |||
width: 40rpx; | |||
height: 21rpx; | |||
margin-right: 30rpx; | |||
margin-top: 33.5rpx; | |||
} | |||
.mod-btn { | |||
position: absolute; | |||
bottom: -80rpx; | |||
left: 50%; | |||
margin-left: -80rpx; | |||
} | |||
/* 头部 */ | |||
.head { | |||
width: 750rpx; | |||
height: 500rpx; | |||
position: relative; | |||
.head-immg{ | |||
width: 118rpx; | |||
height: 61rpx; | |||
position: absolute; | |||
top: 300rpx; | |||
left: 100rpx; | |||
} | |||
} | |||
.logo { | |||
width: 248upx; | |||
height: 248upx; | |||
display: block; | |||
position: absolute; | |||
top: 134rpx; | |||
left: 240.5rpx; | |||
} | |||
/* 输入框 */ | |||
.input { | |||
width: 100%; | |||
height: auto; | |||
padding: 0 105rpx; | |||
box-sizing: border-box; | |||
} | |||
.logo_input { | |||
width: 34rpx; | |||
height: 38rpx; | |||
position: absolute; | |||
top: 25rpx; | |||
left: 0; | |||
} | |||
/* 登录 */ | |||
.button { | |||
width: 630rpx; | |||
height: 86rpx; | |||
background: #2671E2; | |||
box-shadow: 0px 2rpx 20rpx 0px rgba(38, 113, 226, 0.5); | |||
border-radius: 49rpx; | |||
text-align: center; | |||
line-height: 89rpx; | |||
color: #fff; | |||
margin: 0 auto; | |||
margin-top: 239rpx; | |||
font-size: 34rpx; | |||
} | |||
.footer { | |||
width: 100%; | |||
height: 157rpx; | |||
position: absolute; | |||
bottom: 0; | |||
left: 0; | |||
} | |||
.imagesBox { | |||
width: 80rpx; | |||
height: 88rpx; | |||
} | |||
.login { | |||
text-decoration: underline; | |||
text-align: center; | |||
margin-top: 40px; | |||
color: #88909E; | |||
font-size: 28rpx; | |||
} | |||
.textbox { | |||
width: 569rpx; | |||
display: flex; | |||
margin-top: 40rpx; | |||
} | |||
.textbox-1 { | |||
width: 30%; | |||
font-size: 30rpx; | |||
color: #999999; | |||
} | |||
.textbox-11 { | |||
width: 30%; | |||
text-align: right; | |||
font-size: 30rpx; | |||
color: #999999; | |||
} | |||
.textbox-2 { | |||
width: 40%; | |||
} | |||
</style> |
@@ -0,0 +1,328 @@ | |||
<template> | |||
<view class="content"> | |||
<view class="head"> | |||
<view class="text"> | |||
<view class="text1"> | |||
<view style="color: #666666;">输入短信验证码</view> | |||
<view style="color: #303030;margin-top: 20rpx;">短信已发送至{{phone}},请在下方输入框内输入4位数字验证码</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="sction"> | |||
<view class="mama"> | |||
<view class="mamaz"> | |||
<input type="text" v-model="msg" maxlength="4" placeholder="请输入验证码" placeholder-class="input-class" class="input" /> | |||
</view> | |||
<view class="mamay"> | |||
<view class="sada" v-if="sendAuthCode" style="font-size: 35rpx;" @click="getAuthCode">获取验证码</view> | |||
<text class="sada" v-if="!sendAuthCode"> | |||
重新发送 | |||
<text>({{ auth_time }})</text> | |||
</text> | |||
</view> | |||
</view> | |||
<view class="login-btn" :style="{ background: msg == '' ? '#F2F2F2' : '#2671E2' }" @click="denglu"><text | |||
class="">登录</text></view> | |||
<view class="code-login" @click="passwordlogin"><text>密码登录</text></view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
var app = getApp(); | |||
var WXB_SESSION_LOGIN_DATA = 'weapp_session_login_data'; | |||
export default { | |||
data() { | |||
return { | |||
sendAuthCode: true, | |||
auth_time: 0, | |||
msg: '', | |||
phonecet: '', | |||
role:'', | |||
phone:'' | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
var phonese = options.username; | |||
var phonexxz = phonese.substring(0, 3) + '****' + phonese.substring(7); | |||
this.phone = phonexxz, | |||
this.phonecet = options.username, | |||
this.role = options.role | |||
this.sendAuthCode = false; | |||
this.auth_time = 60; | |||
var auth_timetimer = setInterval(() => { | |||
this.auth_time--; | |||
if (this.auth_time <= 0) { | |||
this.sendAuthCode = true; | |||
clearInterval(auth_timetimer); | |||
} | |||
}, 1000); | |||
}, | |||
methods: { | |||
//跳转密码登录页面 | |||
passwordlogin() { | |||
uni.reLaunch({ | |||
url: '/pages/login/index', | |||
}) | |||
}, | |||
//获取验证码 | |||
getAuthCode() { | |||
uni.request({ | |||
url: config.service.sendCode + "?mobile=" + this.phonecet, | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
console.log(data) | |||
// 成功地响应会话信息 | |||
if (data.data.code == 10000) { | |||
util.showSuccess('发送成功'); | |||
this.sendAuthCode = false; | |||
this.auth_time = 60; | |||
var auth_timetimer = setInterval(() => { | |||
this.auth_time--; | |||
if (this.auth_time <= 0) { | |||
this.sendAuthCode = true; | |||
clearInterval(auth_timetimer); | |||
} | |||
}, 1000); | |||
} else { | |||
util.showNone(data.data.message); | |||
return false; | |||
} | |||
}, | |||
}) | |||
}, | |||
//登录 | |||
denglu() { | |||
if (this.msg=='') { | |||
uni.showToast({ | |||
title: '验证码不能为空', | |||
icon: 'none' | |||
}); | |||
return | |||
} | |||
if (this.msg.length == 4) { | |||
let porme = { | |||
loginName: this.phonecet, | |||
password: this.msg | |||
} | |||
uni.request({ | |||
url: config.service.plogin, | |||
method: "POST", | |||
data: porme, | |||
header: { | |||
'content-type': 'application/json', | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
}, | |||
success: (data) => { | |||
// 成功地响应会话信息 | |||
if (data.data.code == 10000) { | |||
util.showSuccess('登录成功'); | |||
var token = { | |||
'token': data.data.data | |||
}; | |||
uni.setStorageSync(WXB_SESSION_LOGIN_DATA, token); //写入缓存 | |||
this.getMenu() | |||
this.getUser() | |||
} else { | |||
util.showNone(data.data.message); | |||
return false; | |||
} | |||
}, | |||
}) | |||
} else { | |||
uni.showToast({ | |||
title: '验证码位数不正确', | |||
icon: 'none' | |||
}); | |||
} | |||
}, | |||
getMenu(){ | |||
this.$u.get("/user/getMenu").then(data => { | |||
uni.setStorageSync("weapp_session_Menu_data", data) | |||
}) | |||
}, | |||
getUser(){ | |||
util.getRequestPromise(config.service.getUser, {}, false, "GET").then(data => { | |||
if (data.zkProperties) { | |||
} else { | |||
data.zkProperties = [{ | |||
id: "", | |||
propertyName: '' | |||
}] | |||
} | |||
let lopan = { | |||
id: data.zkProperties[0].id, | |||
name: data.zkProperties[0].propertyName | |||
} | |||
uni.setStorageSync("fendianindex", 0); //写入缓存 | |||
uni.setStorageSync("weapp_session_userInfo_data", data); //写入缓存 | |||
uni.setStorageSync("buildingID", lopan); //项目id写入缓存 | |||
uni.switchTab({ | |||
url: '/pages/index/index' | |||
}); | |||
}); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
.head { | |||
width: 750rpx; | |||
height:400rpx; | |||
position: relative; | |||
.text{ | |||
width: 100%; | |||
position: absolute; | |||
top: 180rpx; | |||
left: 0rpx; | |||
.text1{ | |||
width: 80%; | |||
margin: 0 auto; | |||
} | |||
} | |||
} | |||
.mama { | |||
width: 620rpx; | |||
display: flex; | |||
border-bottom: 1px solid #E1E1E1; | |||
margin: 60rpx auto; | |||
} | |||
.sadsadasdasdsadasd { | |||
font-size: 34rpx; | |||
font-family: PingFangSC-Medium, PingFang SC; | |||
font-weight: 500; | |||
color: #008EF2; | |||
width: 100%; | |||
text-align: center; | |||
padding-top: 340rpx; | |||
} | |||
.mamaz { | |||
width: 50%; | |||
height: 90rpx; | |||
} | |||
.mamay { | |||
width: 50%; | |||
height: 90rpx; | |||
} | |||
.input { | |||
width: 350rpx; | |||
color: #78DFB0; | |||
height: 100%; | |||
line-height: 90rpx; | |||
font-size: 17px; | |||
color: #171717; | |||
} | |||
.sada { | |||
width: 70%; | |||
line-height: 90rpx; | |||
color: #2B6EFF; | |||
text-align: right; | |||
font-size: 35rpx; | |||
margin-left: 100rpx; | |||
display: block; | |||
} | |||
.content { | |||
margin: 0; | |||
padding: 0; | |||
border-top: 1rpx solid #E0E0E0; | |||
} | |||
.login-text { | |||
font-size: 60rpx; | |||
font-family: PingFang SC; | |||
font-weight: 500; | |||
color: rgba(23, 23, 23, 1); | |||
letter-spacing: 8rpx; | |||
margin-left: 75rpx; | |||
font-weight: bold; | |||
} | |||
.login-input { | |||
border-bottom: 1px solid #e1e1e1; | |||
color: #c9cac9; | |||
margin: 98rpx 64rpx 200rpx 75rpx; | |||
font-size: 17px; | |||
} | |||
.login-btn { | |||
margin: 0 auto; | |||
margin-top: 240rpx; | |||
width: 630rpx; | |||
height: 86rpx; | |||
border-radius: 49rpx; | |||
font-size: 17px; | |||
font-weight: bold; | |||
border: none; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
color: #ffffff; | |||
} | |||
.code-login { | |||
display: flex; | |||
justify-content: center; | |||
margin-top: 40rpx; | |||
color: #D6D7D6; | |||
margin-bottom: 200rpx; | |||
font-size: 30rpx; | |||
} | |||
.log-box { | |||
display: flex; | |||
flex-direction: row; | |||
justify-content: center; | |||
align-items: center; | |||
font-size: 28rpx; | |||
color: #bfc0bf; | |||
margin-bottom: 65rpx; | |||
} | |||
.hengx { | |||
margin: 0 20rpx 0 20rpx; | |||
height: 2rpx; | |||
width: 232rpx; | |||
background: #e1e1e1; | |||
} | |||
.wechat { | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
width: 93rpx; | |||
height: 93rpx; | |||
background: rgba(255, 255, 255, 1); | |||
box-shadow: 0px 10rpx 30rpx rgba(120, 223, 176, 0.22); | |||
border-radius: 50%; | |||
margin: 0 auto; | |||
} | |||
.btn-get { | |||
width: 250rpx; | |||
font-size: 17px; | |||
color: #c9cac9; | |||
position: relative; | |||
top: -290rpx; | |||
right: -450rpx; | |||
} | |||
.input-class { | |||
color: #D6D7D6; | |||
font-size: 17px; | |||
letter-spacing: 1rpx; | |||
} | |||
</style> |
@@ -0,0 +1,116 @@ | |||
<template> | |||
<view class="translation"> | |||
<view style="width: 690rpx;margin: 0 auto;margin-top: 10rpx;"> | |||
<view style="width: 100%;border-bottom: 1px solid #E0E0E0;display: flex;padding-bottom: 10rpx;margin-top: 40rpx;" | |||
v-for="(item,index) in listarr" :key='index' @click="toaidoinfo(item.Content,item.corpusId,item.index)"> | |||
<view style="width: 26rpx;height: 36rpx;margin-top: 4rpx;"> | |||
<image style="width: 26rpx;height: 28rpx;" src="../../static/images/testimg.png" mode=""></image> | |||
</view> | |||
<view v-html="item.Content.onebest" style="color: #666666;font-size: 28rpx;line-height: 36rpx;margin-left: 10rpx;width: 80%;"></view> | |||
<view style="font-size: 28rpx;width: 10%;width: 14%;text-align: right;">{{item.Content.time}}</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
export default { | |||
data() { | |||
return { | |||
customerId:'', | |||
listarr:[], | |||
id:'', | |||
type:'', | |||
tipsFncName: '', // 提醒页面变更的值 | |||
from: '', // 标记需要刷新的来源 | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
this.customerId = options.customerId; | |||
this.id=options.id; | |||
this.type=options.type; | |||
if (options.UpDateEvent) this.tipsFncName = options.UpDateEvent | |||
if (options.from) this.from = options.from | |||
this.searchinfo() | |||
}, | |||
methods: { | |||
formatTime(num) { | |||
//格式化时间格式 | |||
num = num.toFixed(0); | |||
let second = num % 60; | |||
if (second < 10) second = '0' + second; | |||
let min = Math.floor(num / 60); | |||
if (min < 10) min = '0' + min; | |||
return min + ":" + second; | |||
}, | |||
//搜索 | |||
searchinfo(){ | |||
let parames={ | |||
marketingId:this.id, | |||
customerId:this.customerId, | |||
type:this.type | |||
} | |||
this.$u.post("/corpus/pinWordMatching", parames).then(res => { | |||
res.forEach(item=>{ | |||
item.Content=JSON.parse(item.transferContent) | |||
}) | |||
res.forEach(cet=>{ | |||
cet.Content.time=this.formatTime(cet.Content.bg/1000) | |||
}) | |||
this.listarr=res; | |||
}) | |||
}, | |||
//跳转 | |||
toaidoinfo(item,id,index){ | |||
item.customerId=this.customerId; | |||
item.id=id; | |||
item.index=index; | |||
this.infostust(item) | |||
}, | |||
//只有一条的时候 | |||
infostust(item){ | |||
console.log("zobudao") | |||
let d = JSON.parse(JSON.stringify([item])) | |||
d[0].onebest=""; | |||
console.log(d) | |||
const parames = { | |||
pageNum: 1, | |||
pageSize: 100, | |||
query: { | |||
customerId: this.customerId, | |||
} | |||
} | |||
this.$u.post("/corpus/findByPage", parames).then(res => { | |||
uni.setStorageSync("entrance", 2); //写入缓存 | |||
uni.setStorageSync("searchobj", d[0]); //写入缓存 | |||
if(res[0].merge==0){ | |||
let newobj = res[0]; | |||
if (this.tipsFncName) { | |||
uni.$emit(this.tipsFncName, d[0]) | |||
uni.$emit('newobjStatus', newobj.status) | |||
uni.navigateBack() | |||
return | |||
} | |||
uni.navigateTo({ | |||
url: `/pages/mine/details2?customerId=${newobj.customerId}&status=${newobj.status}&itemobj=${JSON.stringify(d[0])}&stateisshow=${'2'}` | |||
}) | |||
}else{ | |||
let newobj = res[0]; | |||
uni.navigateTo({ | |||
url: `/pages/mine/details?customerId=${newobj.customerId}&status=${newobj.status}&itemobj=${JSON.stringify(d[0])}&stateisshow=${'2'}` | |||
}) | |||
} | |||
}) | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
</style> |
@@ -0,0 +1,237 @@ | |||
<template> | |||
<view class="box"> | |||
<view class="conmsg" v-if="allList.length!=0"> | |||
<view class="conmsg-msg"> | |||
<view v-for="(item,index) in allList" :key="index"> | |||
<view class=""> | |||
<view class="conmsg-msg-lab" style="border: none;"> | |||
<view class="conmsg-msg-lab-1"> | |||
{{item.name}} | |||
</view> | |||
</view> | |||
<view class="con-msg-con" | |||
:style="{borderBottom:index==allList.length-1?'none':'1px solid #E0E0E0'}"> | |||
<view v-for='(item1,i) in item.children' :key='i' @click="Edittag(item,item1,index,i)" | |||
:style="{border:item1.selected==0?'1px solid #0A6EE9':'1px solid #E0E0E0'}" | |||
class="chebox"> | |||
{{item1.label}} | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="submit"> | |||
<view class="btn" @click="submit"> | |||
确定 | |||
</view> | |||
</view> | |||
<view class="" style="height: 220rpx;"></view> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
allList:[], | |||
customerId:'' | |||
} | |||
}, | |||
onLoad(e) { | |||
this.customerId=e.id; | |||
this.getListByType() | |||
}, | |||
methods: { | |||
Edittag(item,item1,index,i){ | |||
if(this.allList[index].children[i].selected==0){ | |||
this.allList[index].children[i].selected=1; | |||
}else{ | |||
this.allList[index].children[i].selected=0; | |||
} | |||
this.$forceUpdate() | |||
}, | |||
// 字典表接口 | |||
getListByType() { | |||
this.$u.get("/matchKeywords/findManualCalibration", { | |||
customerId: this.customerId, | |||
type:2 | |||
}) | |||
.then(res => { | |||
res.forEach(item1 => { | |||
item1.children.map(item => { | |||
if (item.isInterval == 0) { | |||
item.label = item.name + item.unit + '-' + item.endName + item | |||
.unit; | |||
} else { | |||
item.label = item.name | |||
} | |||
item.value = item.id; | |||
}) | |||
}) | |||
this.allList = res | |||
}) | |||
}, | |||
// 提交 | |||
submit() { | |||
let param = { | |||
keywordIds:'', | |||
id: this.customerId, | |||
} | |||
let str = [] | |||
this.allList.map(item => { | |||
item.children.map(item1 => { | |||
if (item1.selected == 0) { | |||
str.push(item1.keywordsId) | |||
} | |||
}) | |||
}) | |||
str = str.join(',') | |||
param.keywordIds = str | |||
this.$u.post("matchKeywords/updateManualCalibration", param).then(res => { | |||
uni.showToast({ | |||
title: '操作成功', | |||
icon: 'none', | |||
success: () => { | |||
let sdd={ | |||
keywordIds: this.customerId, | |||
id: this.customerId, | |||
bg:0, | |||
speaker:0 | |||
} | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: sdd | |||
}); | |||
uni.navigateBack() | |||
} | |||
}) | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box { | |||
width: 100%; | |||
height: 100%; | |||
background: #F8F8F8; | |||
overflow: hidden; | |||
} | |||
.conmsg { | |||
background: #FFFFFF; | |||
margin-top: 20rpx; | |||
.conmsg-title { | |||
height: 92rpx; | |||
line-height: 92rpx; | |||
font-weight: bold; | |||
padding: 0 30rpx; | |||
// font-weight: 500; | |||
color: #303030; | |||
font-size: 32rpx; | |||
border-bottom: 1px solid #E0E0E0; | |||
} | |||
.conmsg-msg { | |||
padding: 0 30rpx; | |||
.conmsg-msg-lab { | |||
height: 102rpx; | |||
display: flex; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
color: #333333; | |||
border-bottom: 1px solid #E0E0E0; | |||
line-height: 102rpx; | |||
.conmsg-msg-lab-1 { | |||
display: flex; | |||
min-width: 136rpx; | |||
.star { | |||
color: #E7483C; | |||
line-height: 108rpx; | |||
} | |||
} | |||
.conmsg-msg-lab-inp { | |||
margin-top: 30rpx; | |||
margin-left: 44rpx; | |||
} | |||
.conmsg-msg-lab-img { | |||
width: 14rpx; | |||
height: 30rpx; | |||
margin-top: 6rpx; | |||
margin-left: auto; | |||
image { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
.submit { | |||
position: fixed; | |||
bottom: 20rpx; | |||
left: 20rpx; | |||
height: 120rpx; | |||
background: #FFFFFF; | |||
.btn { | |||
// margin: 60rpx auto; | |||
text-align: center; | |||
width: 690rpx; | |||
height: 88rpx; | |||
background: #2671E2; | |||
border-radius: 8rpx; | |||
font-size: 32tpx; | |||
font-weight: 400; | |||
color: #FFFFFF; | |||
line-height: 88rpx; | |||
} | |||
} | |||
.con-msg-con { | |||
display: flex; | |||
flex-wrap: wrap; | |||
// justify-content: space-around; | |||
border-bottom: 1px solid #E0E0E0; | |||
padding-bottom: 16rpx; | |||
.chebox { | |||
// width: 20%; | |||
height: 60rpx; | |||
line-height: 60rpx; | |||
// margin: 10rpx 0; | |||
margin-bottom: 25rpx; | |||
margin-right: 20rpx; | |||
border: 1px solid #E0E0E0; | |||
box-sizing: border-box; | |||
padding: 0 10rpx; | |||
} | |||
} | |||
.sexchose { | |||
width: 120rpx; | |||
height: 60rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #E0E0E0; | |||
text-align: center; | |||
line-height: 60rpx; | |||
margin-right: 20rpx; | |||
} | |||
</style> |
@@ -0,0 +1,239 @@ | |||
<template> | |||
<view class="box"> | |||
<!-- 顾问选择 --> | |||
<view class="nextcon"> | |||
下一位接待顾问:{{agentList[0].name||'没有下一位了'}} | |||
</view> | |||
<view class="tab"> | |||
<!-- <view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 0 }" @click="tabtimetap(0)">全部</view> | |||
</view> --> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 1 }" @click="tabtimetap(1)">排队顾问</view> | |||
</view> | |||
<view class="tabbox"> | |||
<view :class="{ activecllasscet: activeTotal == 2 }" @click="tabtimetap(2)">暂停顾问</view> | |||
</view> | |||
</view> | |||
<view class="content"> | |||
<view v-if="activeAgentList.length>0"> | |||
<view v-for="(item,index) in activeAgentList" :key="index"> | |||
<view class="content-tips"> | |||
<view class="top"> | |||
<view class="tit"> | |||
<view class="img"> | |||
{{item.name.slice(0,1)}} | |||
</view> | |||
<view class="test"> | |||
{{item.name}} | |||
</view> | |||
</view> | |||
<!-- <view class="state"> | |||
<view class="point" v-if="activeTotal==1"></view> | |||
{{activeTotal==1?'接待中':'空闲'}} | |||
</view> --> | |||
</view> | |||
<view class="reception"> | |||
<view class="" style="line-height: 50rpx;"> | |||
今日接待:<test class="num">{{item.receiveNum||0}}</test> | |||
</view> | |||
<view class="btn" @click="changeAgentStatus(item.agentId)"> | |||
{{activeTotal==1?'暂停':'恢复'}} | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<view class="nolist" v-else> | |||
暂无数据 | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
data(){ | |||
return{ | |||
value:"", | |||
activeTotal: 1, | |||
agentList:[], | |||
pausedAgentList:[], | |||
houseId:'' | |||
} | |||
}, | |||
onLoad() { | |||
this.houseId = uni.getStorageSync('buildingID').id; | |||
this.changeAgentListShow() | |||
this.changePausedAgentListShow() | |||
}, | |||
onPullDownRefresh() { | |||
this.changeAgentListShow() | |||
this.changePausedAgentListShow() | |||
setTimeout(function () { | |||
uni.stopPullDownRefresh(); | |||
}, 1000); | |||
}, | |||
computed: { | |||
activeAgentList() { | |||
return this.activeTotal == 1 ? this.agentList : this.pausedAgentList | |||
}, | |||
}, | |||
methods:{ | |||
tabtimetap(idx){ | |||
// console.log(idx) | |||
this.activeTotal=idx | |||
}, | |||
changeAgentListShow() { | |||
this.$u.get("/zkAgentPool/nextFreeAgent?itemId="+this.houseId).then(res => { | |||
this.agentList = res; | |||
}) | |||
}, | |||
// 获取暂停的经纪人列表 | |||
changePausedAgentListShow() { | |||
this.$u.get("/zkAgentPool/stopAgentList?itemId="+this.houseId).then(res => { | |||
this.pausedAgentList = res; | |||
}) | |||
}, | |||
changeAgentStatus(id) { | |||
let content = ""; | |||
if (this.activeTotal == 1) { | |||
content = "确定当前顾问暂停接待?"; | |||
} else { | |||
content = "确定取消暂停?"; | |||
} | |||
uni.showModal({ | |||
content, | |||
cancelColor: "#999999", | |||
success: res => { | |||
if (res.confirm) { | |||
this.$u.get("/zkAgentPool/update", { | |||
agentId: id, | |||
status: this.activeTotal == 1 ? 2 : 0 | |||
}).then(res => { | |||
uni.showToast({ | |||
icon: "none", | |||
title: "操作成功", | |||
}) | |||
this.changeAgentListShow() | |||
this.changePausedAgentListShow() | |||
}) | |||
} | |||
}, | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.box{ | |||
background: #F8F8F8; | |||
width: 100%; | |||
height: 100vh; | |||
font-size: 30rpx; | |||
font-weight: 400; | |||
// line-height: 30px; | |||
.tab{ | |||
height: 88rpx; | |||
border-bottom: 1px solid #E0E0E0; | |||
background: #FFFFFF; | |||
display: flex; | |||
align-items: center; | |||
.tabbox { | |||
flex: 1; | |||
height: 100%; | |||
text-align: center; | |||
line-height: 92rpx; | |||
color: #666666; | |||
font-size: 28rpx; | |||
display: flex; | |||
justify-content: center; | |||
.activecllasscet { | |||
border-bottom: 2px solid #2671E2; | |||
color: #2671E2; | |||
font-weight: 600; | |||
} | |||
} | |||
} | |||
.nextcon{ | |||
height: 78rpx; | |||
background: #F4F8FD; | |||
color: #2671E2; | |||
text-align: center; | |||
line-height: 78rpx; | |||
} | |||
.content-tips{ | |||
background: #fff; | |||
padding: 0 30rpx; | |||
height: 168rpx; | |||
margin-bottom: 20rpx; | |||
overflow: hidden; | |||
.top{ | |||
margin-top: 19rpx; | |||
display: flex; | |||
justify-content: space-between; | |||
.tit{ | |||
height: 52rpx; | |||
display: flex; | |||
.img{ | |||
width: 52rpx; | |||
height: 52rpx; | |||
border-radius: 50%; | |||
line-height: 47rpx; | |||
text-align: center; | |||
background: #FFFFFF; | |||
border: 1px solid #C9C9C9; | |||
margin-right: 20rpx; | |||
} | |||
.test{ | |||
font-weight: 600; | |||
color: #333333; | |||
margin-top: 6rpx; | |||
} | |||
} | |||
.state{ | |||
display: flex; | |||
.point{ | |||
width: 12rpx; | |||
height: 12rpx; | |||
background: #2B6EFF; | |||
border-radius: 50%; | |||
margin-right: 9rpx; | |||
margin-top: 16rpx; | |||
} | |||
} | |||
} | |||
.reception{ | |||
display: flex; | |||
font-weight: 400; | |||
width: 100%; | |||
margin-top: 28rpx; | |||
justify-content: space-between; | |||
color: #666666; | |||
line-height: 30rpx; | |||
.btn{ | |||
width: 100rpx; | |||
height: 48rpx; | |||
background: #FFFFFF; | |||
border-radius: 4rpx; | |||
border: 1px solid #C9C9C9; | |||
text-align: center; | |||
line-height: 48rpx; | |||
color: #333333; | |||
font-size: 28rpx; | |||
} | |||
} | |||
} | |||
} | |||
.nolist{ | |||
text-align: center; | |||
height: 300rpx; | |||
color: #CCCCCC; | |||
line-height: 300rpx; | |||
} | |||
</style> |