5-03 成人体验版
|
|
@ -0,0 +1,56 @@
|
|||
<script>
|
||||
export default {
|
||||
methods: {},
|
||||
onLaunch() {
|
||||
// 版本更新
|
||||
const updateManager = wx.getUpdateManager()
|
||||
// 请求完新版本信息的回调
|
||||
updateManager.onCheckForUpdate(function(res) {
|
||||
console.log("是否有新版本", res.hasUpdate)
|
||||
})
|
||||
// 新版本下载成功
|
||||
updateManager.onUpdateReady(function() {
|
||||
wx.showModal({
|
||||
title: '更新提示',
|
||||
content: '新版本已经准备好,是否重启应用?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
|
||||
updateManager.applyUpdate()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
// 新版本下载失败
|
||||
updateManager.onUpdateFailed(function() {
|
||||
wx.showModal({
|
||||
title: '新版本更新失败',
|
||||
content: '请退出并移除小程序,重新打开...',
|
||||
})
|
||||
})
|
||||
// 系统信息
|
||||
// uni.getSystemInfo({
|
||||
// success: e => {
|
||||
// let res = uni.getMenuButtonBoundingClientRect()
|
||||
// let statusBarHeight = {
|
||||
// BarTopHeight: res.top,
|
||||
// BarTopLineHeight: res.height + 10,
|
||||
// BarMarginTop: Number(res.top + res.height + 10)
|
||||
// }
|
||||
// this.$store.commit("handleBarHeight", statusBarHeight);
|
||||
// console.log("系统信息", e, res)
|
||||
// }
|
||||
// })
|
||||
},
|
||||
mounted() {},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
|
|
@ -0,0 +1,429 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="content weightPages">
|
||||
<view class="title" v-if="isConnection == 0">连接中,请稍后</view>
|
||||
<view class="title" v-if="isConnection == 1">连接成功,请开始测量</view>
|
||||
<view class="title" v-if="isConnection == 2" @click="openBluetoothAdapter">连接失败,点击重新连接</view>
|
||||
<view class="text">{{text}}</view>
|
||||
<view class="image">
|
||||
<image src="/BLEPages/static/F018P01.gif" v-if="type==1"></image>
|
||||
<image src="/BLEPages/static/F018P01.gif" v-if="type==2"></image>
|
||||
</view>
|
||||
<view class="tips">
|
||||
<text>提示:</text>
|
||||
<text>1.请确定设备是开机状态</text>
|
||||
<text>2.请确定手机蓝牙、位置信息已打开</text>
|
||||
<text>3.ios系统需打开设置—>应用—>微信里的蓝牙权限</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
var myTime;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
text: "",
|
||||
height: "",
|
||||
weight: "",
|
||||
imp: 0,
|
||||
type: 1,
|
||||
uuid1: "",
|
||||
uuid2: "",
|
||||
uuid3: "",
|
||||
macAddr: "",
|
||||
deviceId: "",
|
||||
serviceId: "",
|
||||
Unload: false,
|
||||
isConnection: 0, //是否连接成功
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isConnected", "isBluetoothTyle"]),
|
||||
info() {
|
||||
return this.user
|
||||
}
|
||||
},
|
||||
onUnload: function() {
|
||||
let that = this
|
||||
if (!that.Unload) {
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
console.log("返回上一个页面")
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
that.text = ""
|
||||
if (options && options.deviceId) {
|
||||
that.macAddr = options.deviceId
|
||||
that.deviceId = options.deviceId
|
||||
that.createBLEConnection()
|
||||
}
|
||||
that.onBLEConnectionStateChange()
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
isConnected: function() {
|
||||
let that = this
|
||||
if (!that.isConnected) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
isBluetoothTyle: function() {
|
||||
let that = this
|
||||
if (!that.isBluetoothTyle) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 初始化蓝牙
|
||||
openBluetoothAdapter() {
|
||||
let that = this
|
||||
that.type = 1
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.isConnection = 0
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
},
|
||||
fail: e => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
// 开始搜寻附近的蓝牙外围设备
|
||||
startBluetoothDeviceDiscovery() {
|
||||
let that = this
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
allowDuplicatesKey: false,
|
||||
interval: 500, //上报设备的间隔
|
||||
services: [
|
||||
"FFE0",
|
||||
],
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
var that = this;
|
||||
that.isConnection = 0
|
||||
uni.onBluetoothDeviceFound(res => {
|
||||
res.devices.forEach(device => {
|
||||
if (!device.name && !device.localName) {
|
||||
return
|
||||
}
|
||||
if (device.deviceId.indexOf(that.deviceId) != -1) {
|
||||
that.stopBluetoothDevicesDiscovery()
|
||||
clearTimeout(myTime);
|
||||
let buff = device.advertisData.slice(-6)
|
||||
device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址
|
||||
let tempMac = Array.from(device.mac)
|
||||
tempMac.reverse()
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
that.macAddr = device.macAddr
|
||||
that.deviceId = device.deviceId;
|
||||
that.createBLEConnection()
|
||||
return;
|
||||
}
|
||||
})
|
||||
});
|
||||
that.handleMyTime()
|
||||
},
|
||||
handleMyTime() {
|
||||
var that = this;
|
||||
myTime = setTimeout(function() {
|
||||
if (!that.macAddr) {
|
||||
clearTimeout(myTime);
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
}, 20000);
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery() {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log("停止搜索蓝牙设备", e)
|
||||
},
|
||||
});
|
||||
},
|
||||
// 监听蓝牙连接状态
|
||||
onBLEConnectionStateChange() {
|
||||
let that = this
|
||||
uni.onBLEConnectionStateChange(function(res) {
|
||||
console.log("监听蓝牙连接状态", res.connected)
|
||||
if (!res.connected) {
|
||||
clearTimeout(myTime);
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
that.$store.commit("changeConnected", res.connected);
|
||||
})
|
||||
},
|
||||
// 连接蓝牙
|
||||
createBLEConnection() {
|
||||
let that = this;
|
||||
uni.createBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.getBLEDeviceServices();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
console.log("设备连接失败,请重新连接", res);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取设备的UUID
|
||||
*/
|
||||
getBLEDeviceServices() {
|
||||
let serviceList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceServices({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log("获取设备的UUID成功", res)
|
||||
serviceList = res.services;
|
||||
for (let i = 0; i < serviceList.length; i++) {
|
||||
let service = serviceList[i];
|
||||
if (service.uuid.indexOf("FFE0") != -1) {
|
||||
that.isConnection = 1
|
||||
that.serviceId = service.uuid;
|
||||
that.getBLEDeviceCharacteristics();
|
||||
console.log("设备的FFE0的serviceId: " + that.serviceId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取设备的UUID失败:', res)
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取指定服务的特征值
|
||||
*/
|
||||
getBLEDeviceCharacteristics() {
|
||||
let characteristicsList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceCharacteristics({
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
success: res => {
|
||||
console.log("服务的特征值成功", res)
|
||||
for (let i = 0; i < res.characteristics.length; i++) {
|
||||
let item = res.characteristics[i];
|
||||
if (item.uuid.indexOf('0000FFE1') != -1) {
|
||||
that.uuid1 = item.uuid //下发数据
|
||||
} else if (item.uuid.indexOf('0000FFE2') != -1) {
|
||||
that.uuid2 = item.uuid //监听数据
|
||||
} else if (item.uuid.indexOf('0000FFE3') != -1) {
|
||||
that.uuid3 = item.uuid //写入设置
|
||||
that.notifyBLECharacteristicValue()
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取特征值失败:', JSON.stringify(res))
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 开启订阅特征值
|
||||
* read: true, //读,write: true, //写,notify: true, //广播
|
||||
*/
|
||||
notifyBLECharacteristicValue() {
|
||||
let that = this;
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
state: true, // 启用 notify 功能
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
characteristicId: that.uuid3,
|
||||
success(res) {
|
||||
uni.onBLECharacteristicValueChange(function(res) {
|
||||
let value = that.$tools.ab2hex(res.value, "");
|
||||
let num = value.substring(18, 19)
|
||||
let dw = value.substring(19, 20)
|
||||
let type = value.substring(8, 10)
|
||||
let typeInfo = value.substring(10, 12)
|
||||
if (type == "10") {
|
||||
let data = parseInt(value.substring(13, 18), 16)
|
||||
let dw1 = "kg"
|
||||
let dw2 = "kg"
|
||||
if (dw == "1") {
|
||||
dw1 = "斤"
|
||||
dw2 = "jin"
|
||||
}
|
||||
if (dw == "4") {
|
||||
dw1 = "st:lb"
|
||||
dw2 = "st"
|
||||
data = 1 * data + 5
|
||||
}
|
||||
if (dw == "6") {
|
||||
dw1 = "lb"
|
||||
dw2 = "lb"
|
||||
}
|
||||
if (num == "1") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 10
|
||||
}
|
||||
if (num == "2") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 100
|
||||
}
|
||||
if (num == "3") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 1000
|
||||
}
|
||||
if (typeInfo == "01") {
|
||||
that.text = "您的实时体重是:" + data + dw1
|
||||
}
|
||||
if (typeInfo == "02") {
|
||||
that.text = "您的体重是:" + data + dw1
|
||||
that.weight = data + dw2
|
||||
console.log("稳定体重:", value, that.weight)
|
||||
}
|
||||
}
|
||||
if (type == "11") {
|
||||
if (typeInfo == "03") {
|
||||
that.imp = parseInt(value.substring(17, 22), 16)
|
||||
}
|
||||
console.log("体脂:", that.imp)
|
||||
}
|
||||
if (type == "14") { //身高模式
|
||||
that.height = parseInt(value.substring(10, 14), 16) / 10
|
||||
that.type = 2
|
||||
console.log("身高模式:", that.height)
|
||||
}
|
||||
if (type == "30") {
|
||||
console.log("测量完成", that.weight, that.height, that.imp)
|
||||
if (that.imp == 0) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: "体脂测量失败,是否保存本次测量结果?",
|
||||
cancelText: "放弃",
|
||||
confirmText: "保存",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
that.imp = 0
|
||||
that.handleGetMeasure()
|
||||
} else {
|
||||
that.Unload = true
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
that.handleGetMeasure()
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
fail(res) {
|
||||
console.log("测量失败", res.value);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 保存测量结果
|
||||
handleGetMeasure() {
|
||||
let that = this
|
||||
that.$model.getmeasure({
|
||||
weight: that.weight,
|
||||
imp: that.imp,
|
||||
ecode: that.macAddr,
|
||||
height: that.height,
|
||||
familyid: that.info.familyid,
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
that.$tools.msg("测量成功")
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.info.familyid,
|
||||
});
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: that.info.birthday,
|
||||
familyid: that.info.familyid,
|
||||
height: that.height,
|
||||
sex: that.info.sex,
|
||||
});
|
||||
} else {
|
||||
console.log("测量失败", res.message)
|
||||
that.$tools.msg(res.message)
|
||||
}
|
||||
that.Unload = true
|
||||
setTimeout(function() {
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.switchTab({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 200)
|
||||
})
|
||||
},
|
||||
handleBack(ind) {
|
||||
let that = this
|
||||
that.text = ""
|
||||
that.Unload = true
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
clearTimeout(myTime)
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter() {
|
||||
let that = this;
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('蓝牙模块关闭成功');
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
var that = this;
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log('断开蓝牙连接成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
|
@ -0,0 +1,383 @@
|
|||
<template>
|
||||
<view class="content weightPages">
|
||||
<view class="title" v-if="isConnection == 0">连接中,请稍后</view>
|
||||
<view class="title" v-if="isConnection == 1">连接成功,请开始测量</view>
|
||||
<view class="title" v-if="isConnection == 2" @click="openBluetoothAdapter">连接失败,点击重新连接</view>
|
||||
<view class="text">{{textW}}</view>
|
||||
<view class="text">{{textH}}</view>
|
||||
<view class="image">
|
||||
<image src="/BLEPages/static/H01pro.gif"></image>
|
||||
</view>
|
||||
<view class="tips">
|
||||
<text>请确保:</text>
|
||||
<text>1.请确定设备是开机状态</text>
|
||||
<text>2.请确定手机蓝牙、位置信息已打开</text>
|
||||
<text>3.ios系统需打开设置—>应用—>微信里的蓝牙权限</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
var myTime;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
textW: "",
|
||||
textH: "",
|
||||
height: "",
|
||||
weight: "",
|
||||
imp: 0,
|
||||
macAddr: "",
|
||||
deviceId: "",
|
||||
serviceId: "",
|
||||
readId: "",
|
||||
writeId: "",
|
||||
notifyId: "",
|
||||
Unload: false,
|
||||
isConnection: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isConnected", "isBluetoothTyle"]),
|
||||
info() {
|
||||
return this.user
|
||||
}
|
||||
},
|
||||
onUnload: function() {
|
||||
let that = this
|
||||
if (!that.Unload) {
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
console.log("页面返回onUnload")
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isConnected: function() {
|
||||
let that = this
|
||||
if (!that.isConnected) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
isBluetoothTyle: function() {
|
||||
let that = this
|
||||
if (!that.isBluetoothTyle) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
that.textW = ""
|
||||
that.textH = ""
|
||||
if (options && options.deviceId) {
|
||||
that.macAddr = options.deviceId
|
||||
that.deviceId = options.deviceId
|
||||
that.createBLEConnection()
|
||||
}
|
||||
that.onBLEConnectionStateChange()
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 重新连接
|
||||
openBluetoothAdapter() {
|
||||
let that = this
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.isConnection = 0
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
},
|
||||
fail: e => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
// 监听蓝牙连接状态
|
||||
onBLEConnectionStateChange() {
|
||||
let that = this
|
||||
uni.onBLEConnectionStateChange(function(res) {
|
||||
console.log("监听蓝牙连接状态", res.connected)
|
||||
if (!res.connected) {
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
that.$store.commit("changeConnected", res.connected);
|
||||
})
|
||||
},
|
||||
// 开始搜寻附近的蓝牙外围设备
|
||||
startBluetoothDeviceDiscovery() {
|
||||
let that = this
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
allowDuplicatesKey: false,
|
||||
interval: 500, //上报设备的间隔
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
var that = this;
|
||||
that.isConnection = 0
|
||||
uni.onBluetoothDeviceFound(res => {
|
||||
console.log('开始监听寻找到新设备的事件', res);
|
||||
res.devices.forEach(device => {
|
||||
if (!device.name && !device.localName) {
|
||||
return
|
||||
}
|
||||
if (device.deviceId.indexOf(that.deviceId) != -1) {
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
clearTimeout(myTime);
|
||||
let buff = device.advertisData.slice(-6)
|
||||
device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址
|
||||
let tempMac = Array.from(device.mac)
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
that.deviceId = device.macAddr
|
||||
that.macAddr = device.macAddr
|
||||
that.createBLEConnection()
|
||||
return;
|
||||
}
|
||||
})
|
||||
});
|
||||
that.handleMyTime()
|
||||
},
|
||||
handleMyTime() {
|
||||
var that = this;
|
||||
myTime = setTimeout(function() {
|
||||
if (!that.macAddr) {
|
||||
clearTimeout(myTime);
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
}, 20000);
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery() {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log("停止搜索蓝牙设备", e)
|
||||
},
|
||||
});
|
||||
},
|
||||
// 连接蓝牙
|
||||
createBLEConnection() {
|
||||
let that = this;
|
||||
uni.createBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.getBLEDeviceServices();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
console.log("设备连接失败,请重新连接", res);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取设备的UUID
|
||||
*/
|
||||
getBLEDeviceServices() {
|
||||
let serviceList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceServices({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log("获取设备的UUID成功", res)
|
||||
serviceList = res.services;
|
||||
for (let i = 0; i < serviceList.length; i++) {
|
||||
let service = serviceList[i];
|
||||
if (service.uuid.indexOf('FFE0') != -1) {
|
||||
that.serviceId = service.uuid;
|
||||
that.isConnection = 1
|
||||
that.getBLEDeviceCharacteristics(that.deviceId, service.uuid);
|
||||
console.log("设备的FFE0的serviceId: ", that.serviceId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取设备的UUID失败:', res)
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取指定服务的特征值
|
||||
*/
|
||||
getBLEDeviceCharacteristics(deviceId, serviceId) {
|
||||
let characteristicsList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceCharacteristics({
|
||||
deviceId: deviceId,
|
||||
serviceId: serviceId,
|
||||
success: res => {
|
||||
console.log("服务的特征值成功", res)
|
||||
characteristicsList = res.characteristics;
|
||||
for (let i = 0; i < characteristicsList.length; i++) {
|
||||
let item = characteristicsList[i];
|
||||
if (item.uuid.indexOf("FFE1") != -1) {
|
||||
if (item.properties.notify == true) {
|
||||
that.notifyId = item.uuid
|
||||
}
|
||||
if (item.properties.write == true) {
|
||||
that.writeId = item.uuid
|
||||
}
|
||||
if (item.properties.read) {
|
||||
that.readId = item.uuid
|
||||
}
|
||||
}
|
||||
}
|
||||
// 打开监听
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
deviceId,
|
||||
serviceId,
|
||||
characteristicId: that.notifyId,
|
||||
state: true,
|
||||
})
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
deviceId,
|
||||
serviceId,
|
||||
characteristicId: that.writeId,
|
||||
state: true,
|
||||
})
|
||||
uni.onBLECharacteristicValueChange(function(res) {
|
||||
let value = that.$tools.ab2hex(res.value, '');
|
||||
let weight = parseInt(value.substring(4, 8), 16) / 100
|
||||
let height = parseInt(value.substring(30, 34), 16) / 10
|
||||
let imp0 = value.substring(28, 30) + value.substring(34, 36)
|
||||
let imp = parseInt(imp0, 16)
|
||||
that.imp = imp
|
||||
that.textW = "您的体重是:" + weight + 'kg'
|
||||
that.textH = "您的身高是:" + height + 'cm'
|
||||
that.weight = weight + 'kg'
|
||||
that.height = height
|
||||
console.log("测量完成", that.weight, that.height, that.imp)
|
||||
if (imp == 0) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: "体脂测量失败,是否保存本次测量结果?",
|
||||
cancelText: "放弃",
|
||||
confirmText: "保存",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
that.handleGetMeasure()
|
||||
} else {
|
||||
that.Unload = true
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
} else {
|
||||
that.handleGetMeasure()
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取特征值失败:', JSON.stringify(res))
|
||||
}
|
||||
})
|
||||
},
|
||||
// 保存测量结果
|
||||
handleGetMeasure() {
|
||||
console.log("保存结果")
|
||||
let that = this
|
||||
that.$model.getmeasure({
|
||||
weight: that.weight,
|
||||
imp: that.imp,
|
||||
ecode: that.macAddr,
|
||||
height: that.height ? that.height : that.info.height,
|
||||
familyid: that.info.familyid,
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
that.$tools.msg("测量成功")
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.info.familyid,
|
||||
});
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: that.info.birthday,
|
||||
familyid: that.info.familyid,
|
||||
height: that.height ? that.height : that.info.height,
|
||||
sex: that.info.sex,
|
||||
});
|
||||
} else {
|
||||
console.log("测量失败", res.message)
|
||||
that.$tools.msg(res.message)
|
||||
}
|
||||
that.Unload = true
|
||||
setTimeout(function() {
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.switchTab({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 200)
|
||||
|
||||
})
|
||||
},
|
||||
handleBack() {
|
||||
let that = this
|
||||
that.textW = ""
|
||||
that.textH = ""
|
||||
that.Unload = true
|
||||
that.Unload = true
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter() {
|
||||
let that = this;
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('蓝牙模块关闭成功');
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
var that = this;
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log('断开蓝牙连接成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
|
@ -0,0 +1,449 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="content weightPages">
|
||||
<view class="title" v-if="isConnection == 0">连接中,请稍后</view>
|
||||
<view class="title" v-if="isConnection == 1">连接成功,请开始测量</view>
|
||||
<view class="title" v-if="isConnection == 2" @click="openBluetoothAdapter">连接失败,点击重新连接</view>
|
||||
<view class="text">{{text}}</view>
|
||||
<view class="text">{{textH}}</view>
|
||||
<view class="image">
|
||||
<image src="/BLEPages/static/H09B.gif" v-if="type == 1"></image>
|
||||
<image src="/BLEPages/static/H09B2.gif" v-if="type == 2"></image>
|
||||
</view>
|
||||
<view class="tips">
|
||||
<text>提示:</text>
|
||||
<text>1.请确定设备是开机状态</text>
|
||||
<text>2.请确定手机蓝牙、位置信息已打开</text>
|
||||
<text>3.ios系统需打开设置—>应用—>微信里的蓝牙权限</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
var myTime;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
text: "",
|
||||
textH: "",
|
||||
height: "",
|
||||
weight: "",
|
||||
imp: 0,
|
||||
type: 1,
|
||||
uuid1: "",
|
||||
uuid2: "",
|
||||
uuid3: "",
|
||||
macAddr: "",
|
||||
deviceId: "",
|
||||
serviceId: "",
|
||||
Unload: false,
|
||||
isConnection: 0, //是否连接成功
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isConnected", "isBluetoothTyle"]),
|
||||
info() {
|
||||
return this.user
|
||||
}
|
||||
},
|
||||
onUnload: function() {
|
||||
let that = this
|
||||
if (!that.Unload) {
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
that.text = ""
|
||||
that.textH = ""
|
||||
that.imp = 0
|
||||
if (options && options.deviceId) {
|
||||
that.macAddr = options.deviceId
|
||||
that.deviceId = options.deviceId
|
||||
that.createBLEConnection()
|
||||
}
|
||||
that.onBLEConnectionStateChange()
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
isConnected: function() {
|
||||
let that = this
|
||||
if (!that.isConnected) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
isBluetoothTyle: function() {
|
||||
let that = this
|
||||
if (!that.isBluetoothTyle) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 初始化蓝牙
|
||||
openBluetoothAdapter() {
|
||||
let that = this
|
||||
that.type = 1
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.isConnection = 0
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
},
|
||||
fail: e => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
// 开始搜寻附近的蓝牙外围设备
|
||||
startBluetoothDeviceDiscovery() {
|
||||
let that = this
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
allowDuplicatesKey: false,
|
||||
interval: 500, //上报设备的间隔
|
||||
services: [
|
||||
"FFE0",
|
||||
],
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
var that = this;
|
||||
that.isConnection = 0
|
||||
uni.onBluetoothDeviceFound(res => {
|
||||
res.devices.forEach(device => {
|
||||
if (!device.name && !device.localName) {
|
||||
return
|
||||
}
|
||||
if (device.deviceId.indexOf(that.deviceId) != -1) {
|
||||
that.stopBluetoothDevicesDiscovery()
|
||||
clearTimeout(myTime);
|
||||
let buff = device.advertisData.slice(-6)
|
||||
device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址
|
||||
let tempMac = Array.from(device.mac)
|
||||
tempMac.reverse()
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
that.macAddr = device.macAddr
|
||||
that.deviceId = device.deviceId;
|
||||
that.createBLEConnection()
|
||||
return;
|
||||
}
|
||||
})
|
||||
});
|
||||
that.handleMyTime()
|
||||
},
|
||||
handleMyTime() {
|
||||
var that = this;
|
||||
myTime = setTimeout(function() {
|
||||
if (!that.macAddr) {
|
||||
clearTimeout(myTime);
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
}, 20000);
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery() {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log("停止搜索蓝牙设备", e)
|
||||
},
|
||||
});
|
||||
},
|
||||
// 监听蓝牙连接状态
|
||||
onBLEConnectionStateChange() {
|
||||
let that = this
|
||||
uni.onBLEConnectionStateChange(function(res) {
|
||||
console.log("监听蓝牙连接状态", res.connected)
|
||||
if (!res.connected) {
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
that.$store.commit("changeConnected", res.connected);
|
||||
})
|
||||
},
|
||||
// 连接蓝牙
|
||||
createBLEConnection() {
|
||||
let that = this;
|
||||
uni.createBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.getBLEDeviceServices();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
console.log("设备连接失败,请重新连接", res);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取设备的UUID
|
||||
*/
|
||||
getBLEDeviceServices() {
|
||||
let serviceList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceServices({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log("获取设备的UUID成功", res)
|
||||
serviceList = res.services;
|
||||
for (let i = 0; i < serviceList.length; i++) {
|
||||
let service = serviceList[i];
|
||||
if (service.uuid.indexOf("FFE0") != -1) {
|
||||
that.isConnection = 1
|
||||
that.serviceId = service.uuid;
|
||||
that.getBLEDeviceCharacteristics();
|
||||
console.log("设备的FFE0的serviceId: " + that.serviceId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取设备的UUID失败:', res)
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取指定服务的特征值
|
||||
*/
|
||||
getBLEDeviceCharacteristics() {
|
||||
let characteristicsList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceCharacteristics({
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
success: res => {
|
||||
console.log("服务的特征值成功", res)
|
||||
for (let i = 0; i < res.characteristics.length; i++) {
|
||||
let item = res.characteristics[i];
|
||||
if (item.uuid.indexOf('0000FFE1') != -1) {
|
||||
that.uuid1 = item.uuid //下发数据
|
||||
} else if (item.uuid.indexOf('0000FFE2') != -1) {
|
||||
that.uuid2 = item.uuid //监听数据
|
||||
} else if (item.uuid.indexOf('0000FFE3') != -1) {
|
||||
that.uuid3 = item.uuid //写入设置
|
||||
}
|
||||
}
|
||||
that.sendData()
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
characteristicId: that.uuid2,
|
||||
state: true,
|
||||
})
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
characteristicId: that.uuid3,
|
||||
state: true,
|
||||
})
|
||||
uni.onBLECharacteristicValueChange(function(res) {
|
||||
let value = that.$tools.ab2hex(res.value, "");
|
||||
let num = value.substring(18, 19)
|
||||
let dw = value.substring(19, 20)
|
||||
let type = value.substring(8, 10)
|
||||
let typeInfo = value.substring(10, 12)
|
||||
if (type == "10") {
|
||||
let data = parseInt(value.substring(13, 18), 16)
|
||||
let dw1 = "kg"
|
||||
let dw2 = "kg"
|
||||
if (dw == "1") {
|
||||
dw1 = "斤"
|
||||
dw2 = "jin"
|
||||
}
|
||||
if (dw == "4") {
|
||||
dw1 = "st:lb"
|
||||
dw2 = "st"
|
||||
data = 1 * data + 5
|
||||
}
|
||||
if (dw == "6") {
|
||||
dw1 = "lb"
|
||||
dw2 = "lb"
|
||||
}
|
||||
if (num == "1") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 10
|
||||
}
|
||||
if (num == "2") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 100
|
||||
}
|
||||
if (num == "3") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 1000
|
||||
}
|
||||
if (typeInfo == "01") {
|
||||
that.text = "您的实时体重是:" + data + dw1
|
||||
}
|
||||
if (typeInfo == "02") {
|
||||
that.text = "您的体重是:" + data + dw1
|
||||
that.weight = data + dw2
|
||||
console.log("稳定体重:", value, that.weight)
|
||||
}
|
||||
}
|
||||
if (type == "14") {
|
||||
that.height = parseInt(value.substring(10, 14), 16) / 10
|
||||
that.textH = "您的身高是:" + that.height + "cm"
|
||||
that.type = 2
|
||||
console.log("稳定身高:", that.height)
|
||||
}
|
||||
if (type == "11") {
|
||||
if (typeInfo == "03" || typeInfo == "04") {
|
||||
that.imp = parseInt(value.substring(17, 22), 16)
|
||||
}
|
||||
console.log("阻抗:", typeInfo, parseInt(value.substring(17, 22), 16))
|
||||
}
|
||||
if (type == "30") {
|
||||
console.log("测量完成", that.weight, that.imp, that.height)
|
||||
if (that.imp == 0) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: "体脂测量失败,是否保存本次测量结果?",
|
||||
cancelText: "放弃",
|
||||
confirmText: "保存",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
that.imp = 0
|
||||
that.handleGetMeasure()
|
||||
} else {
|
||||
console.log("放弃保存")
|
||||
that.Unload = true
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
that.handleGetMeasure()
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取特征值失败:', JSON.stringify(res))
|
||||
}
|
||||
})
|
||||
},
|
||||
// 身高体重体脂模式
|
||||
sendData() {
|
||||
let that = this
|
||||
let j = Number(26 + 3 + 6 + 1).toString(16)
|
||||
let str = "A9002603060100" + j.substr(j.length - 2, 2) + "9A"
|
||||
let buf = new Uint8Array(str.match(/[\da-f]{2}/gi).map(function(h) {
|
||||
return parseInt(h, 16)
|
||||
}))
|
||||
uni.writeBLECharacteristicValue({
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
characteristicId: that.uuid1,
|
||||
value: buf.buffer,
|
||||
success: res => {
|
||||
console.log('下发指令成功', res.errMsg)
|
||||
},
|
||||
fail: res => {
|
||||
console.log("下发指令失败", res);
|
||||
},
|
||||
})
|
||||
},
|
||||
// 保存测量结果
|
||||
handleGetMeasure() {
|
||||
let that = this
|
||||
that.$model.getmeasure({
|
||||
weight: that.weight,
|
||||
imp: that.imp,
|
||||
ecode: that.macAddr,
|
||||
height: that.height,
|
||||
familyid: that.info.familyid,
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.info.familyid,
|
||||
});
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: that.info.birthday,
|
||||
familyid: that.info.familyid,
|
||||
height: that.height,
|
||||
sex: that.info.sex,
|
||||
});
|
||||
that.$tools.msg("测量成功")
|
||||
} else {
|
||||
console.log("测量失败", res.message)
|
||||
that.$tools.msg(res.message)
|
||||
}
|
||||
that.Unload = true
|
||||
setTimeout(function() {
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.switchTab({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 200)
|
||||
})
|
||||
},
|
||||
handleBack(ind) {
|
||||
let that = this
|
||||
that.text = ""
|
||||
that.textH = ""
|
||||
that.Unload = true
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter() {
|
||||
let that = this;
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('蓝牙模块关闭成功');
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
var that = this;
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log('断开蓝牙连接成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
|
@ -0,0 +1,432 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="content weightPages">
|
||||
<view class="title" v-if="isConnection == 0">连接中,请稍后</view>
|
||||
<view class="title" v-if="isConnection == 1">连接成功,请开始测量</view>
|
||||
<view class="title" v-if="isConnection == 2" @click="openBluetoothAdapter">连接失败,点击重新连接</view>
|
||||
<view class="text">{{text}}</view>
|
||||
<view class="image">
|
||||
<image src="/BLEPages/static/Hd01bt01.gif" v-if="type==1"></image>
|
||||
<image src="/BLEPages/static/Hd01bt02.gif" v-if="type==2"></image>
|
||||
</view>
|
||||
<view class="tips">
|
||||
<text>提示:</text>
|
||||
<text>1.请确定设备是开机状态</text>
|
||||
<text>2.请确定手机蓝牙、位置信息已打开</text>
|
||||
<text>3.ios系统需打开设置—>应用—>微信里的蓝牙权限</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
var myTime;
|
||||
let cnt = 0
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
text: "",
|
||||
height: "",
|
||||
weight: "",
|
||||
imp: 0,
|
||||
type: 1,
|
||||
uuid1: "",
|
||||
uuid2: "",
|
||||
uuid3: "",
|
||||
macAddr: "",
|
||||
deviceId: "",
|
||||
serviceId: "",
|
||||
Unload: false,
|
||||
pageNav: false,
|
||||
isConnection: 0, //是否连接成功
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isConnected", "isBluetoothTyle"]),
|
||||
info() {
|
||||
return this.user
|
||||
}
|
||||
},
|
||||
onUnload: function() {
|
||||
let that = this
|
||||
if (!that.Unload) {
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
console.log("测量页返回1")
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
cnt = 0
|
||||
that.text = ""
|
||||
if (options && options.deviceId) {
|
||||
that.macAddr = options.deviceId
|
||||
that.deviceId = options.deviceId
|
||||
that.createBLEConnection()
|
||||
}
|
||||
that.onBLEConnectionStateChange()
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
isConnected: function() {
|
||||
let that = this
|
||||
if (!that.isConnected) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
isBluetoothTyle: function() {
|
||||
let that = this
|
||||
if (!that.isBluetoothTyle) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 初始化蓝牙
|
||||
openBluetoothAdapter() {
|
||||
let that = this
|
||||
cnt = 0
|
||||
that.type = 1
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.isConnection = 0
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
},
|
||||
fail: e => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
// 开始搜寻附近的蓝牙外围设备
|
||||
startBluetoothDeviceDiscovery() {
|
||||
let that = this
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
allowDuplicatesKey: false,
|
||||
interval: 500, //上报设备的间隔
|
||||
services: [
|
||||
"FFE0",
|
||||
],
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
var that = this;
|
||||
that.isConnection = 0
|
||||
uni.onBluetoothDeviceFound(res => {
|
||||
res.devices.forEach(device => {
|
||||
if (!device.name && !device.localName) {
|
||||
return
|
||||
}
|
||||
if (device.deviceId.indexOf(that.deviceId) != -1) {
|
||||
that.stopBluetoothDevicesDiscovery()
|
||||
clearTimeout(myTime);
|
||||
let buff = device.advertisData.slice(-6)
|
||||
device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址
|
||||
let tempMac = Array.from(device.mac)
|
||||
tempMac.reverse()
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
that.macAddr = device.macAddr
|
||||
that.deviceId = device.deviceId;
|
||||
that.createBLEConnection()
|
||||
return;
|
||||
}
|
||||
})
|
||||
});
|
||||
that.handleMyTime()
|
||||
},
|
||||
handleMyTime() {
|
||||
var that = this;
|
||||
myTime = setTimeout(function() {
|
||||
if (!that.macAddr) {
|
||||
clearTimeout(myTime);
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
}, 20000);
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery() {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log("停止搜索蓝牙设备", e)
|
||||
},
|
||||
});
|
||||
},
|
||||
// 监听蓝牙连接状态
|
||||
onBLEConnectionStateChange() {
|
||||
let that = this
|
||||
uni.onBLEConnectionStateChange(function(res) {
|
||||
console.log("监听蓝牙连接状态", res.connected)
|
||||
if (!res.connected) {
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
that.$store.commit("changeConnected", res.connected);
|
||||
})
|
||||
},
|
||||
// 连接蓝牙
|
||||
createBLEConnection() {
|
||||
let that = this;
|
||||
uni.createBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.getBLEDeviceServices();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
console.log("设备连接失败,请重新连接", res);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取设备的UUID
|
||||
*/
|
||||
getBLEDeviceServices() {
|
||||
let serviceList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceServices({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log("获取设备的UUID成功", res)
|
||||
serviceList = res.services;
|
||||
for (let i = 0; i < serviceList.length; i++) {
|
||||
let service = serviceList[i];
|
||||
if (service.uuid.indexOf("FFE0") != -1) {
|
||||
that.isConnection = 1
|
||||
that.serviceId = service.uuid;
|
||||
that.getBLEDeviceCharacteristics();
|
||||
console.log("设备的FFE0的serviceId: " + that.serviceId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取设备的UUID失败:', res)
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取指定服务的特征值
|
||||
*/
|
||||
getBLEDeviceCharacteristics() {
|
||||
let characteristicsList = [];
|
||||
let that = this;
|
||||
uni.getBLEDeviceCharacteristics({
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
success: res => {
|
||||
console.log("服务的特征值成功", res)
|
||||
for (let i = 0; i < res.characteristics.length; i++) {
|
||||
let item = res.characteristics[i];
|
||||
if (item.uuid.indexOf('FFE1') != -1) {
|
||||
that.uuid1 = item.uuid //下发数据
|
||||
} else if (item.uuid.indexOf('FFE2') != -1) {
|
||||
that.uuid2 = item.uuid //监听数据
|
||||
that.notifyBLECharacteristicValue()
|
||||
} else if (item.uuid.indexOf('FFE3') != -1) {
|
||||
that.uuid3 = item.uuid //写入设置
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: res => {
|
||||
console.log('获取特征值失败:', JSON.stringify(res))
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 开启订阅特征值
|
||||
* read: true, //读,write: true, //写,notify: true, //广播
|
||||
*/
|
||||
notifyBLECharacteristicValue() {
|
||||
let that = this;
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
state: true, // 启用 notify 功能
|
||||
deviceId: that.deviceId,
|
||||
serviceId: that.serviceId,
|
||||
characteristicId: that.uuid2,
|
||||
success(res) {
|
||||
uni.onBLECharacteristicValueChange(function(res) {
|
||||
let value = that.$tools.ab2hex(res.value, "");
|
||||
let num = value.substring(18, 19)
|
||||
let dw = value.substring(19, 20)
|
||||
let type = value.substring(8, 10)
|
||||
let typeInfo = value.substring(10, 12)
|
||||
console.log("value", value)
|
||||
if (type == "10") {
|
||||
let data = parseInt(value.substring(13, 18), 16)
|
||||
let dw1 = "kg"
|
||||
let dw2 = "kg"
|
||||
if (dw == "1") {
|
||||
dw1 = "斤"
|
||||
dw2 = "jin"
|
||||
}
|
||||
if (dw == "4") {
|
||||
dw1 = "st:lb"
|
||||
dw2 = "st"
|
||||
data = 1 * data + 5
|
||||
}
|
||||
if (dw == "6") {
|
||||
dw1 = "lb"
|
||||
dw2 = "lb"
|
||||
}
|
||||
if (num == "1") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 10
|
||||
}
|
||||
if (num == "2") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 100
|
||||
}
|
||||
if (num == "3") {
|
||||
data = parseInt(value.substring(13, 18), 16) / 1000
|
||||
}
|
||||
if (typeInfo == "01") {
|
||||
that.text = "您的实时体重是:" + data + dw1
|
||||
}
|
||||
if (typeInfo == "02") {
|
||||
that.text = "您的体重是:" + data + dw1
|
||||
that.weight = data + dw2
|
||||
console.log("稳定体重:", value, that.weight)
|
||||
}
|
||||
}
|
||||
if (type == "11") {
|
||||
that.type = 2
|
||||
if (typeInfo == "02") {
|
||||
cnt = cnt + 1;
|
||||
}
|
||||
if (typeInfo == "03") {
|
||||
that.imp = parseInt(value.substring(17, 22), 16)
|
||||
}
|
||||
if (cnt >= 2) {
|
||||
console.log("阻抗值shibai", cnt)
|
||||
that.imp = 0
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: "体脂测量失败,是否保存本次测量结果?",
|
||||
cancelText: "放弃",
|
||||
confirmText: "保存",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
that.imp = 0
|
||||
that.handleGetMeasure()
|
||||
} else {
|
||||
that.Unload = true
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (type == "30") {
|
||||
console.log("测量完成", that.weight)
|
||||
that.handleGetMeasure()
|
||||
}
|
||||
});
|
||||
},
|
||||
fail(res) {
|
||||
console.log("测量失败", res.value);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 保存测量结果
|
||||
handleGetMeasure() {
|
||||
let that = this
|
||||
that.$model.getmeasure({
|
||||
weight: that.weight,
|
||||
imp: that.imp,
|
||||
ecode: that.macAddr,
|
||||
height: that.info.height,
|
||||
familyid: that.info.familyid,
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
that.$tools.msg("测量成功")
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.info.familyid,
|
||||
});
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: that.info.birthday,
|
||||
familyid: that.info.familyid,
|
||||
height: that.info.height,
|
||||
sex: that.info.sex,
|
||||
});
|
||||
} else {
|
||||
console.log("测量失败", res.message)
|
||||
that.$tools.msg(res.message)
|
||||
}
|
||||
that.Unload = true
|
||||
setTimeout(function() {
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.switchTab({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 200)
|
||||
})
|
||||
},
|
||||
handleBack() {
|
||||
let that = this
|
||||
that.Unload = true
|
||||
clearTimeout(myTime)
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter() {
|
||||
let that = this;
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('蓝牙模块关闭成功');
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
var that = this;
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log('断开蓝牙连接成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="content weightPages">
|
||||
<view class="title" v-if="isConnection == 0">连接中,请稍后</view>
|
||||
<view class="title" v-if="isConnection == 1">连接成功,请开始测量</view>
|
||||
<view class="title" v-if="isConnection == 2" @click="openBluetoothAdapter">连接失败,点击重新连接</view>
|
||||
<view class="text">{{text}}</view>
|
||||
<view class="image">
|
||||
<image src="/BLEPages/static/L01.gif"></image>
|
||||
</view>
|
||||
<view class="tips">
|
||||
<text>提示:</text>
|
||||
<text>1.请确定设备是开机状态</text>
|
||||
<text>2.请确定手机蓝牙、位置信息已打开</text>
|
||||
<text>3.ios系统需打开设置—>应用—>微信里的蓝牙权限</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
let myTime
|
||||
const plugin = requirePlugin("sdkPlugin").AiLink;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
text: "",
|
||||
height: "",
|
||||
weight: "",
|
||||
imp: 0,
|
||||
macAddr: "",
|
||||
deviceId: "",
|
||||
serviceId: "",
|
||||
Unload: false,
|
||||
stopblue: true,
|
||||
isConnection: 0, //是否连接成功
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isConnected", "isBluetoothTyle"]),
|
||||
info() {
|
||||
return this.user
|
||||
}
|
||||
},
|
||||
onUnload: function() {
|
||||
let that = this
|
||||
if (!that.Unload) {
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
console.log("测量页返回1")
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
that.text = ""
|
||||
if (options && options.deviceId) {
|
||||
that.deviceId = options.deviceId
|
||||
console.log(0)
|
||||
that.openBluetoothAdapter()
|
||||
}
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
isConnected: function() {
|
||||
let that = this
|
||||
if (!that.isConnected) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
isBluetoothTyle: function() {
|
||||
let that = this
|
||||
if (!that.isBluetoothTyle) {
|
||||
that.handleBack()
|
||||
that.isConnection = 2
|
||||
}
|
||||
},
|
||||
stopblue: function() {
|
||||
let that = this
|
||||
if (!that.stopblue) {
|
||||
console.log("停止成功", that.weight, that.imp)
|
||||
if (that.imp == 0) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: "体脂测量失败,是否保存本次测量结果?",
|
||||
cancelText: "放弃",
|
||||
confirmText: "保存",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
that.imp = 0
|
||||
that.handleGetMeasure()
|
||||
} else {
|
||||
that.Unload = true
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
that.handleGetMeasure()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化蓝牙
|
||||
openBluetoothAdapter() {
|
||||
let that = this
|
||||
that.text = ""
|
||||
that.stopblue = true
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.isConnection = 0
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
},
|
||||
fail: e => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
// 开始搜寻附近的蓝牙外围设备
|
||||
startBluetoothDeviceDiscovery() {
|
||||
let that = this
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
allowDuplicatesKey: true,
|
||||
services: [
|
||||
"F0A0",
|
||||
],
|
||||
success: res => {
|
||||
that.isConnection = 0
|
||||
that.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: res => {
|
||||
that.isConnection = 2
|
||||
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery() {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log("停止搜索蓝牙设备", e)
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
var that = this;
|
||||
that.isConnection = 1
|
||||
uni.onBluetoothDeviceFound(res => {
|
||||
res.devices.forEach(device => {
|
||||
if (!device.name && !device.localName) {
|
||||
return
|
||||
}
|
||||
if (device.advertisServiceUUIDs[0].indexOf("F0A0") !== -1) {
|
||||
clearTimeout(myTime);
|
||||
let value = that.$tools.ab2hex(device.advertisData)
|
||||
let parseDataRes = plugin.parseBroadcastData(device.advertisData)
|
||||
let analyzeData = plugin.analyzeBroadcastScaleData(parseDataRes)
|
||||
let analyzeDataText = analyzeData.text
|
||||
let data = analyzeData.data
|
||||
console.log("analyzeData", parseDataRes, analyzeData)
|
||||
if (parseDataRes.status == 1) {
|
||||
let dw1 = "kg"
|
||||
let dw2 = "kg"
|
||||
if (data.weightUnit == "1") {
|
||||
dw1 = "斤"
|
||||
dw2 = "jin"
|
||||
}
|
||||
if (data.weightUnit == "4") {
|
||||
dw1 = "st:lb"
|
||||
dw2 = "st"
|
||||
data = 1 * data + 5
|
||||
}
|
||||
if (data.weightUnit == "6") {
|
||||
dw1 = "lb"
|
||||
dw2 = "lb"
|
||||
}
|
||||
if (data.weightDecimal == "1") {
|
||||
data.weight = data.weight / 10
|
||||
}
|
||||
if (data.weightDecimal == "2") {
|
||||
data.weight = data.weight / 100
|
||||
}
|
||||
if (data.weightDecimal == "3") {
|
||||
data.weight = data.weight / 1000
|
||||
}
|
||||
that.text = "您的体重是:" + data.weight + dw1
|
||||
if (data.weightStatus == 1 || analyzeDataText.indexOf('阻抗测量失败') != -1) {
|
||||
let buffer = device.advertisData.slice(0, 8)
|
||||
device.mac = new Uint8Array(buffer)
|
||||
let tempMac = Array.from(device.mac)
|
||||
tempMac.reverse()
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
that.macAddr = device.macAddr
|
||||
that.deviceId = device.deviceId;
|
||||
that.weight = data.weight + dw2
|
||||
that.imp = data.adc
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
return that.stopblue = false
|
||||
},
|
||||
});
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
that.handleMyTime()
|
||||
},
|
||||
handleMyTime() {
|
||||
var that = this;
|
||||
myTime = setTimeout(function() {
|
||||
if (!that.macAddr) {
|
||||
clearTimeout(myTime);
|
||||
that.Unload = true
|
||||
that.isConnection = 2
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
}
|
||||
}, 20000);
|
||||
},
|
||||
// 保存测量结果
|
||||
handleGetMeasure() {
|
||||
let that = this
|
||||
that.$model.getmeasure({
|
||||
weight: that.weight,
|
||||
imp: that.imp,
|
||||
ecode: that.macAddr,
|
||||
height: that.info.height,
|
||||
familyid: that.info.familyid,
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
that.$tools.msg("测量成功")
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.info.familyid,
|
||||
});
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: that.info.birthday,
|
||||
familyid: that.info.familyid,
|
||||
height: that.info.height,
|
||||
sex: that.info.sex,
|
||||
});
|
||||
} else {
|
||||
console.log("测量失败", res.message)
|
||||
that.$tools.msg(res.message)
|
||||
}
|
||||
that.Unload = true
|
||||
setTimeout(function() {
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.switchTab({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 200)
|
||||
})
|
||||
},
|
||||
handleBack() {
|
||||
let that = this
|
||||
that.Unload = true
|
||||
clearTimeout(myTime)
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter() {
|
||||
let that = this;
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('蓝牙模块关闭成功');
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
var that = this;
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log('断开蓝牙连接成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -0,0 +1,363 @@
|
|||
@font-face {
|
||||
font-family: 'iconfont'; /* Project id 2887906 */
|
||||
src: url('https://at.alicdn.com/t/font_2887906_wl80j95s0c.woff2?t=1648878564422') format('woff2'),
|
||||
url('https://at.alicdn.com/t/font_2887906_wl80j95s0c.woff?t=1648878564422') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_2887906_wl80j95s0c.ttf?t=1648878564422') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-biaozhunhua:before {
|
||||
content: "\e60b";
|
||||
}
|
||||
|
||||
.icon-shejiguifan:before {
|
||||
content: "\e640";
|
||||
}
|
||||
|
||||
.icon-tizhongcheng:before {
|
||||
content: "\e63f";
|
||||
}
|
||||
|
||||
.icon-baogao1:before {
|
||||
content: "\e620";
|
||||
}
|
||||
|
||||
.icon-tizhong1:before {
|
||||
content: "\e616";
|
||||
}
|
||||
|
||||
.icon-sharpicons_checklist:before {
|
||||
content: "\e804";
|
||||
}
|
||||
|
||||
.icon-hengxian:before {
|
||||
content: "\e657";
|
||||
}
|
||||
|
||||
.icon-lbm:before {
|
||||
content: "\e6b7";
|
||||
}
|
||||
|
||||
.icon-fatlevel:before {
|
||||
content: "\e63d";
|
||||
}
|
||||
|
||||
.icon-fat_r:before {
|
||||
content: "\e62d";
|
||||
}
|
||||
|
||||
.icon-fat_w:before {
|
||||
content: "\e78e";
|
||||
}
|
||||
|
||||
.icon-bone:before {
|
||||
content: "\e610";
|
||||
}
|
||||
|
||||
.icon-kcal:before {
|
||||
content: "\e60c";
|
||||
}
|
||||
|
||||
.icon-visceral:before {
|
||||
content: "\e60d";
|
||||
}
|
||||
|
||||
.icon-muscle:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.icon-body:before {
|
||||
content: "\e638";
|
||||
}
|
||||
|
||||
.icon-water:before {
|
||||
content: "\e651";
|
||||
}
|
||||
|
||||
.icon-muscleval:before {
|
||||
content: "\e949";
|
||||
}
|
||||
|
||||
.icon-protein:before {
|
||||
content: "\e94a";
|
||||
}
|
||||
|
||||
.icon-proteinval:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.icon-bodyage:before {
|
||||
content: "\e6b2";
|
||||
}
|
||||
|
||||
.icon-height1:before {
|
||||
content: "\e6eb";
|
||||
}
|
||||
|
||||
.icon-shang:before {
|
||||
content: "\e68a";
|
||||
}
|
||||
|
||||
.icon-xia:before {
|
||||
content: "\e798";
|
||||
}
|
||||
|
||||
.icon-sfr:before {
|
||||
content: "\e617";
|
||||
}
|
||||
|
||||
.icon-yisheng3:before {
|
||||
content: "\e6a3";
|
||||
}
|
||||
|
||||
.icon-yisheng_1:before {
|
||||
content: "\e633";
|
||||
}
|
||||
|
||||
.icon-switch-ON-copy-copy:before {
|
||||
content: "\fc23";
|
||||
}
|
||||
|
||||
.icon-switch-ON-copy-copy1:before {
|
||||
content: "\fc25";
|
||||
}
|
||||
|
||||
.icon-shuzhuangtu:before {
|
||||
content: "\e604";
|
||||
}
|
||||
|
||||
.icon-jilu:before {
|
||||
content: "\e69e";
|
||||
}
|
||||
|
||||
.icon-lishixiao:before {
|
||||
content: "\e8bd";
|
||||
}
|
||||
|
||||
.icon-jiantou_xiangxia:before {
|
||||
content: "\eb0a";
|
||||
}
|
||||
|
||||
.icon-jiantou_xiangshang:before {
|
||||
content: "\eb0b";
|
||||
}
|
||||
|
||||
.icon-tizhong:before {
|
||||
content: "\e682";
|
||||
}
|
||||
|
||||
.icon-jiaoxuepinggu-01:before {
|
||||
content: "\e63b";
|
||||
}
|
||||
|
||||
.icon-qiehuan1:before {
|
||||
content: "\e7d7";
|
||||
}
|
||||
|
||||
.icon-head:before {
|
||||
content: "\e8d1";
|
||||
}
|
||||
|
||||
.icon-quxiao:before {
|
||||
content: "\e664";
|
||||
}
|
||||
|
||||
.icon-fenxiang:before {
|
||||
content: "\e60a";
|
||||
}
|
||||
|
||||
.icon-touxiang:before {
|
||||
content: "\e61f";
|
||||
}
|
||||
|
||||
.icon-pingtai:before {
|
||||
content: "\f4ec";
|
||||
}
|
||||
|
||||
.icon-dianhuatianchong:before {
|
||||
content: "\e678";
|
||||
}
|
||||
|
||||
.icon-xinxi:before {
|
||||
content: "\e648";
|
||||
}
|
||||
|
||||
.icon-bianji3:before {
|
||||
content: "\e62b";
|
||||
}
|
||||
|
||||
.icon-gonglve:before {
|
||||
content: "\f4e4";
|
||||
}
|
||||
|
||||
.icon-shoucang:before {
|
||||
content: "\f4f8";
|
||||
}
|
||||
|
||||
.icon-pinglun:before {
|
||||
content: "\f5b0";
|
||||
}
|
||||
|
||||
.icon-shijian-mianxing-0:before {
|
||||
content: "\e6a2";
|
||||
}
|
||||
|
||||
.icon-hezuo:before {
|
||||
content: "\f4e5";
|
||||
}
|
||||
|
||||
.icon-shouhou:before {
|
||||
content: "\f5dd";
|
||||
}
|
||||
|
||||
.icon-pinglun-08:before {
|
||||
content: "\fc1d";
|
||||
}
|
||||
|
||||
.icon-weixin:before {
|
||||
content: "\e637";
|
||||
}
|
||||
|
||||
.icon-QQ:before {
|
||||
content: "\e667";
|
||||
}
|
||||
|
||||
.icon-weight:before {
|
||||
content: "\e62a";
|
||||
}
|
||||
|
||||
.icon-height:before {
|
||||
content: "\e609";
|
||||
}
|
||||
|
||||
.icon-bmi:before {
|
||||
content: "\e785";
|
||||
}
|
||||
|
||||
.icon-shoucang1:before {
|
||||
content: "\e603";
|
||||
}
|
||||
|
||||
.icon-qiehuan:before {
|
||||
content: "\f4ee";
|
||||
}
|
||||
|
||||
.icon-yazi-copy:before {
|
||||
content: "\f5b6";
|
||||
}
|
||||
|
||||
.icon-hear:before {
|
||||
content: "\e8af";
|
||||
}
|
||||
|
||||
.icon-zanwu:before {
|
||||
content: "\e626";
|
||||
}
|
||||
|
||||
.icon-shuimian:before {
|
||||
content: "\e959";
|
||||
}
|
||||
|
||||
.icon-wenjian-xinliweiji:before {
|
||||
content: "\e72d";
|
||||
}
|
||||
|
||||
.icon-yundong:before {
|
||||
content: "\e810";
|
||||
}
|
||||
|
||||
.icon-yinshi2:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.icon-gerendingzhi:before {
|
||||
content: "\e605";
|
||||
}
|
||||
|
||||
.icon-top-chengchangquxian:before {
|
||||
content: "\e61e";
|
||||
}
|
||||
|
||||
.icon-duibi2:before {
|
||||
content: "\e6b8";
|
||||
}
|
||||
|
||||
.icon-tubiao--copy:before {
|
||||
content: "\ec58";
|
||||
}
|
||||
|
||||
.icon-jilu1:before {
|
||||
content: "\e686";
|
||||
}
|
||||
|
||||
.icon-xiangxia:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.icon-kongradio:before {
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
.icon-radio:before {
|
||||
content: "\e653";
|
||||
}
|
||||
|
||||
.icon-arrow-left:before {
|
||||
content: "\e685";
|
||||
}
|
||||
|
||||
.icon-arrow-down:before {
|
||||
content: "\e687";
|
||||
}
|
||||
|
||||
.icon-arrow-right:before {
|
||||
content: "\e688";
|
||||
}
|
||||
|
||||
.icon-tishi:before {
|
||||
content: "\e797";
|
||||
}
|
||||
|
||||
.icon-yazi:before {
|
||||
content: "\e612";
|
||||
}
|
||||
|
||||
.icon-shengao:before {
|
||||
content: "\e739";
|
||||
}
|
||||
|
||||
.icon-liangdu-:before {
|
||||
content: "\e606";
|
||||
}
|
||||
|
||||
.icon-aixin:before {
|
||||
content: "\f4cf";
|
||||
}
|
||||
|
||||
.icon-yqfqiehuan:before {
|
||||
content: "\e61b";
|
||||
}
|
||||
|
||||
.icon-female:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-dangao:before {
|
||||
content: "\e608";
|
||||
}
|
||||
|
||||
.icon-quxian:before {
|
||||
content: "\e629";
|
||||
}
|
||||
|
||||
.icon-baogao:before {
|
||||
content: "\e630";
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="wrapper" v-if="isDrawe">
|
||||
<view class="bg" @click="clear"></view>
|
||||
<view class="wrapper_box">
|
||||
<view class="top">
|
||||
<image class="headimage mt-10" v-if="userinfo.headimg" :src="userinfo.headimg"></image>
|
||||
<view class="overflow">{{userinfo.nickname||userinfo.name}}</view>
|
||||
</view>
|
||||
<view class="drawerList">
|
||||
<view v-if="List.length">
|
||||
<view class="drawerList_item" v-for="(item, index) in List" :key="index" @click="toggle(item)">
|
||||
<image v-if="item.headimg" :src="item.headimg" class="image1"></image>
|
||||
<view class="right">
|
||||
<view class="name">
|
||||
<view class="overflow">
|
||||
{{item.name}}
|
||||
</view>
|
||||
<view class="dangqian" v-if="item.id == userinfo.familyid">当前</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view>{{item.mage}}</view>
|
||||
<view>{{item.sex==0?'未知':item.sex==1?'男':'女'}}</view>
|
||||
<view>{{item.type}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="add">
|
||||
<view @click="addInfo('add')">
|
||||
+
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "familayList", "isDrawe"]),
|
||||
userinfo() {
|
||||
return this.user
|
||||
},
|
||||
List() {
|
||||
return this.familayList
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 切换用户
|
||||
toggle(val) {
|
||||
let that = this
|
||||
uni.setStorageSync('familyid', val.familyid)
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: val.birthday,
|
||||
familyid: val.familyid,
|
||||
height: val.height,
|
||||
sex: val.sex,
|
||||
});
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: val.familyid,
|
||||
});
|
||||
that.$store.commit("changeDrawe", false);
|
||||
},
|
||||
//添加
|
||||
addInfo(type) {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/me/adduser?type=" + type
|
||||
})
|
||||
},
|
||||
clear() {
|
||||
this.$store.commit("changeDrawe", false);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.bg {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
height: 100vh;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.uniDrawer {
|
||||
width: 220px;
|
||||
background-color: #fff;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
@keyframes uniDrawer {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 20rpx;
|
||||
width: 220px;
|
||||
height: calc(100vh - 100px);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
|
||||
.name {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.overflow {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="header-con">
|
||||
<view class="header" v-if="token">
|
||||
<view class="left">
|
||||
<image :src="user.headimg" class="headimage mr-10" @click="handleDrawer"></image>
|
||||
<view>
|
||||
<view class="name" @click="handleDrawer">
|
||||
<text class="overflow">{{user.name}}</text>
|
||||
<icon class="iconfont icon-yqfqiehuan"></icon>
|
||||
</view>
|
||||
<view class="age">
|
||||
<view>
|
||||
性别:{{!user.sex?"未知":user.sex==1?'男':'女'}}
|
||||
</view>
|
||||
<view>
|
||||
年龄:{{user.mage?user.mage:"0岁"}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="celiang_r" @click="handleBluetoothClick">
|
||||
<icon class="t-icon t-icon-tizhongcheng"></icon>
|
||||
<text>上秤测量</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header2" v-else @click="handleLogin">
|
||||
<view class="text"><text>登录</text>查看更多信息</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- denglu -->
|
||||
<userLogin></userLogin>
|
||||
<!-- 左侧 -->
|
||||
<leftdrawer></leftdrawer>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
import userLogin from '@/components/userLogin.vue'
|
||||
import leftdrawer from "@/components/drawer/drawer.vue"
|
||||
export default {
|
||||
components: {
|
||||
userLogin,
|
||||
leftdrawer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
devType: "",
|
||||
deviceId: ""
|
||||
}
|
||||
},
|
||||
props: {
|
||||
token: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
},
|
||||
mounted() {
|
||||
// this.token = uni.getStorageSync('token')
|
||||
},
|
||||
methods: {
|
||||
// 上称测量
|
||||
handleBluetoothClick() {
|
||||
let that = this
|
||||
if (!that.token) {
|
||||
that.$store.commit("changeUserLogin", true)
|
||||
return
|
||||
}
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.$store.commit("changeBluetooth", true);
|
||||
if (that.devType && that.deviceId) {
|
||||
that.$tools.handlePages(that.devType, that.deviceId)
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: "/pages/search/devType"
|
||||
})
|
||||
console.log('初始化蓝牙成功:' + e.errMsg);
|
||||
},
|
||||
fail: err => {
|
||||
console.log('初始化蓝牙失败:' + err.errMsg);
|
||||
return this.$tools.getBluetoothAdapter(err)
|
||||
}
|
||||
});
|
||||
},
|
||||
// 登录
|
||||
handleLogin() {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
},
|
||||
handleDrawer() {
|
||||
this.$store.commit("changeDrawe", true);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
|
@ -0,0 +1,351 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<view class="slide-box" v-for="(item, index) in listData" :key="index">
|
||||
<view class="slide-list" @touchstart="touchStart($event, index)" @touchend="touchEnd($event, index)"
|
||||
@touchmove="touchMove($event, index)" @tap="recover(index)"
|
||||
:style="{ transform: 'translate3d(' + item.slide_x + 'px, 0, 0)' }">
|
||||
<view class="now-message-info" hover-class="uni-item--hover" :style="{ width: windowWidth + 'px' }"
|
||||
@click="clickItemMethod(item)">
|
||||
<view class="list">
|
||||
<view class="item" :class="[type!=1?'leftChild':'']">
|
||||
<view class="time">
|
||||
<icon class="t-icon t-icon-shijian-mianxing-0"></icon>
|
||||
<text>{{item.createtime}}</text>
|
||||
</view>
|
||||
<view v-if="type!=1">{{item.height}}<text>身高</text></view>
|
||||
<view>{{item.weight}}<text>体重</text></view>
|
||||
<view>{{item.bmi}}<text>BMI</text></view>
|
||||
<view v-if="type==1">{{item.fat_r}}<text>脂肪率</text></view>
|
||||
<icon v-if="type==1" class="iconfont icon-arrow-right"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="group-btn">
|
||||
<view class="btn-div" v-for="(value, key) in button" :key="key" @click="clickMethod(item)"
|
||||
:style="{background: value.background}">
|
||||
{{value.title}}
|
||||
</view>
|
||||
</view>
|
||||
<view style="clear:both"></view>
|
||||
</view>
|
||||
<view class="list-item-border" v-if="border"></view>
|
||||
</view>
|
||||
<!-- <view class="endtext" v-if="!lastPage || page >= lastPage">—— 到底了,看看别的吧 ——</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* m-slide-list 滑动操作列表
|
||||
* @description 滑动操作列表组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=209
|
||||
* @property {Array} list 数据源,格式为:[{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0},{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0}]
|
||||
* @property {Array} button 按钮数据源,格式为:[{title: 'xxx', background:'xxx'},{title: 'xxx', background:'xxx'}]
|
||||
* @property {Boolean} border 边框
|
||||
*/
|
||||
export default {
|
||||
name: 'mark-slide-list',
|
||||
props: {
|
||||
list: { //数据list
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
button: { //按钮数据list
|
||||
type: Array,
|
||||
default () {
|
||||
return [{
|
||||
title: '删除',
|
||||
background: '#ff3b32'
|
||||
}];
|
||||
}
|
||||
},
|
||||
border: { //边框
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowWidth() {
|
||||
return uni.getSystemInfoSync().windowWidth;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
listData: [],
|
||||
start_slide_x: 0,
|
||||
btnWidth: 0,
|
||||
startX: 0,
|
||||
LastX: 0,
|
||||
startTime: 0,
|
||||
itemIndex: 0,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.listData = this.clone(this.list)
|
||||
// this.getList(1)
|
||||
},
|
||||
watch: {
|
||||
list: {
|
||||
handler: function(val, oldval) {
|
||||
this.listData = this.clone(this.list)
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clone(data) {
|
||||
const type = typeof data
|
||||
let obj;
|
||||
if (type === 'array') {
|
||||
obj = [];
|
||||
} else if (type === 'object') {
|
||||
obj = {};
|
||||
} else {
|
||||
// 不再具有下一层次
|
||||
return data;
|
||||
}
|
||||
if (type === 'array') {
|
||||
for (let i = 0, len = data.length; i < len; i++) {
|
||||
obj.push(this.clone(data[i]));
|
||||
}
|
||||
} else if (type === 'object') {
|
||||
// 对原型上的方法也拷贝了....
|
||||
for (const key in data) {
|
||||
obj[key] = this.clone(data[key]);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
// 滑动开始
|
||||
touchStart(e, index) {
|
||||
if (this.itemIndex == index) {
|
||||
this.itemIndex = index
|
||||
}
|
||||
//记录手指放上去的时间
|
||||
this.startTime = e.timeStamp;
|
||||
//记录滑块的初始位置
|
||||
this.start_slide_x = this.listData[index].slide_x;
|
||||
// 按钮宽度
|
||||
//#ifdef MP-WEIXIN
|
||||
uni.createSelectorQuery().in(this).selectAll('.group-btn').boundingClientRect(res => {
|
||||
if (res != null) {
|
||||
this.btnWidth = res[index].width * -1;
|
||||
}
|
||||
}).exec();
|
||||
//#endif
|
||||
//#ifdef H5 || APP-PLUS
|
||||
uni.createSelectorQuery()
|
||||
.selectAll('.group-btn')
|
||||
.boundingClientRect()
|
||||
.exec(res => {
|
||||
if (res[0] != null) {
|
||||
this.btnWidth = res[0][index].width * -1;
|
||||
}
|
||||
});
|
||||
//#endif
|
||||
// 记录上一次开始时手指所处位置
|
||||
this.startX = e.touches[0].pageX;
|
||||
// 记录上一次手指位置
|
||||
this.lastX = this.startX;
|
||||
//初始化非当前滑动消息列的位置
|
||||
for (var i in this.listData) {
|
||||
if (index != i) {
|
||||
this.listData[i].slide_x = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 滑动中
|
||||
touchMove(e, index) {
|
||||
const endX = e.touches[0].pageX;
|
||||
const distance = endX - this.lastX;
|
||||
// 预测滑块所处位置
|
||||
const duang = this.listData[index].slide_x + distance;
|
||||
// 如果在可行区域内
|
||||
if (duang <= 0 && duang >= this.btnWidth) {
|
||||
this.listData[index].slide_x = duang;
|
||||
}
|
||||
// 此处手指所处位置将成为下次手指移动时的上一次位置
|
||||
this.lastX = endX;
|
||||
},
|
||||
// 滑动结束
|
||||
touchEnd(e, index) {
|
||||
let distance = 10;
|
||||
const endTime = e.timeStamp;
|
||||
const x_end_distance = this.startX - this.lastX;
|
||||
if (Math.abs(endTime - this.startTime) > 200) {
|
||||
distance = this.btnWidth / -2;
|
||||
}
|
||||
// 判断手指最终位置与手指开始位置的位置差距
|
||||
if (x_end_distance > distance) {
|
||||
this.listData[index].slide_x = this.btnWidth;
|
||||
} else if (x_end_distance < distance * -1) {
|
||||
this.listData[index].slide_x = 0;
|
||||
} else {
|
||||
this.listData[index].slide_x = this.start_slide_x;
|
||||
}
|
||||
},
|
||||
// 点击回复原状
|
||||
recover(index) {
|
||||
this.listData[index].slide_x = 0;
|
||||
},
|
||||
/**
|
||||
* 点击按钮触发事件
|
||||
* @param {Object} item 列表数据
|
||||
* @param {Object} buttonItem 按钮数据
|
||||
* @param {Object} index 列表数据key
|
||||
*/
|
||||
clickMethod(item) {
|
||||
if (this.list.length == 1) {
|
||||
this.$tools.msg("只剩一条记录了,不可以删除!")
|
||||
return
|
||||
}
|
||||
this.$emit("changeDelete", item)
|
||||
},
|
||||
// 详情
|
||||
clickItemMethod(item) {
|
||||
if (this.type == 1) {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/me/info?index=" + JSON.stringify(item)
|
||||
})
|
||||
}
|
||||
// this.$emit("click", item)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
.slide-box {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.list-item-border {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.slide-list {
|
||||
transition: all 100ms;
|
||||
transition-timing-function: ease-out;
|
||||
min-width: 200%;
|
||||
|
||||
.now-message-info {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
clear: both;
|
||||
padding: 0 30rpx;
|
||||
background: #f7f7f7;
|
||||
float: left;
|
||||
|
||||
.icon-image {
|
||||
border-radius: 10rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.icon-circle {
|
||||
background: #3396fb;
|
||||
border-radius: 100%;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.list-right {
|
||||
float: left;
|
||||
margin-left: 25rpx;
|
||||
margin-right: 30rpx;
|
||||
|
||||
.list-title {
|
||||
width: 350rpx;
|
||||
line-height: 1.5;
|
||||
overflow: hidden;
|
||||
margin-bottom: 10rpx;
|
||||
color: #333;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-detail {
|
||||
width: 350rpx;
|
||||
font-size: 14px;
|
||||
color: #a9a9a9;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.list-right-1 {
|
||||
float: right;
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
color: #a9a9a9;
|
||||
}
|
||||
}
|
||||
|
||||
.group-btn {
|
||||
float: left;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
min-width: 100rpx;
|
||||
align-items: center;
|
||||
margin-top: 6rpx;
|
||||
|
||||
.btn-div {
|
||||
height: 100rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 0 50rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 100rpx;
|
||||
border-radius: 5px 0 0 5px;
|
||||
}
|
||||
|
||||
.top {
|
||||
background-color: #c4c7cd;
|
||||
}
|
||||
|
||||
.removeM {
|
||||
background-color: #ff3b32;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leftChild {
|
||||
view {
|
||||
width: 18%;
|
||||
}
|
||||
|
||||
.time {
|
||||
width: 32% !important;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,438 @@
|
|||
<template>
|
||||
<view class="calendar-wrapper">
|
||||
<view class="header">
|
||||
<view class="pre" @click="changeMonth('pre')">
|
||||
<icon class="iconfont icon-arrow-left"></icon>
|
||||
</view>
|
||||
<view>{{y+'年'+formatNum(m)+'月'}}</view>
|
||||
<view class="next" @click="changeMonth('next')">
|
||||
<icon class="iconfont icon-arrow-right"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="week">
|
||||
<view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>
|
||||
</view>
|
||||
<view :class="{ hide: !monthOpen }" class="content0" :style="{ height: height }">
|
||||
<view :style="{ top: positionTop + 'rpx' }" class="days">
|
||||
<view class="item" v-for="(item, index) in dates" :key="index">
|
||||
<view class="day" @click="selectOne(item, $event)" :class="{
|
||||
choose: choose == `${item.year}-${item.month}-${item.date}`&&item.isCurM,
|
||||
nolm: !item.isCurM,
|
||||
today: isToday(item.year, item.month, item.date),
|
||||
isWorkDay: isWorkDay(item.year, item.month, item.date)
|
||||
}">
|
||||
{{ Number(item.date) }}
|
||||
</view>
|
||||
<view class="markDay" v-if="isMarkDay(item.year, item.month, item.date)&&item.isCurM"></view>
|
||||
<!-- <view class="today-text" v-if="isToday(item.year, item.month, item.date)">今</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<image src="https://i.loli.net/2020/07/16/2MmZsucVTlRjSwK.png" mode="scaleToFill" v-if="collapsible"
|
||||
@click="toggle" class="weektoggle" :class="{ down: monthOpen }"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ren-calendar',
|
||||
props: {
|
||||
// 星期几为第一天(0为星期日)
|
||||
weekstart: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 标记的日期
|
||||
markDays: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
//是否展示月份切换按钮
|
||||
headerBar: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否展开
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//是否可收缩
|
||||
collapsible: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//未来日期是否不可点击
|
||||
disabledAfter: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
weektext: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
y: new Date().getFullYear(), // 年
|
||||
m: new Date().getMonth() + 1, // 月
|
||||
dates: [], // 当前月的日期数据
|
||||
positionTop: 0,
|
||||
monthOpen: true,
|
||||
choose: '',
|
||||
month: null,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.dates = this.monthDay(this.y, this.m);
|
||||
!this.open && this.toggle();
|
||||
},
|
||||
mounted() {
|
||||
this.y = new Date().getFullYear()
|
||||
this.m = new Date().getMonth() + 1
|
||||
this.month = this.$tools.getDate("m")
|
||||
this.choose = this.getToday().date;
|
||||
},
|
||||
computed: {
|
||||
// 顶部星期栏
|
||||
weekDay() {
|
||||
return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart));
|
||||
},
|
||||
height() {
|
||||
return (this.dates.length / 7) * 80 + 'rpx';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
formatNum(num) {
|
||||
let res = Number(num);
|
||||
return res < 10 ? '0' + res : res;
|
||||
},
|
||||
getToday() {
|
||||
let date = new Date();
|
||||
let y = date.getFullYear();
|
||||
let m = date.getMonth();
|
||||
let d = date.getDate();
|
||||
let week = new Date().getDay();
|
||||
let weekText = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
let formatWeek = '星期' + weekText[week];
|
||||
let today = {
|
||||
date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d),
|
||||
week: formatWeek
|
||||
};
|
||||
return today;
|
||||
},
|
||||
// 获取当前月份数据
|
||||
monthDay(y, month) {
|
||||
let dates = [];
|
||||
let m = Number(month);
|
||||
let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几
|
||||
let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天
|
||||
let lastDayOfLastMonth = new Date(y, m - 1, 0).getDate(); // 上一月的最后一天
|
||||
let weekstart = this.weekstart == 7 ? 0 : this.weekstart;
|
||||
let startDay = (() => {
|
||||
// 周初有几天是上个月的
|
||||
if (firstDayOfMonth == weekstart) {
|
||||
return 0;
|
||||
} else if (firstDayOfMonth > weekstart) {
|
||||
return firstDayOfMonth - weekstart;
|
||||
} else {
|
||||
return 7 - weekstart + firstDayOfMonth;
|
||||
}
|
||||
})();
|
||||
let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的
|
||||
if (endDay == 7) {
|
||||
endDay = 0;
|
||||
}
|
||||
for (let i = 1; i <= startDay; i++) {
|
||||
dates.push({
|
||||
date: this.formatNum(lastDayOfLastMonth - startDay + i),
|
||||
day: weekstart + i - 1 || 7,
|
||||
month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
|
||||
year: m - 1 >= 0 ? y : y - 1
|
||||
});
|
||||
}
|
||||
for (let j = 1; j <= lastDateOfMonth; j++) {
|
||||
dates.push({
|
||||
date: this.formatNum(j),
|
||||
day: (j % 7) + firstDayOfMonth - 1 || 7,
|
||||
month: this.formatNum(m),
|
||||
year: y,
|
||||
isCurM: true //是否当前月份
|
||||
});
|
||||
}
|
||||
for (let k = 1; k <= endDay; k++) {
|
||||
dates.push({
|
||||
date: this.formatNum(k),
|
||||
day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
|
||||
month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
|
||||
year: m + 1 <= 11 ? y : y + 1
|
||||
});
|
||||
}
|
||||
return dates;
|
||||
},
|
||||
isWorkDay(y, m, d) {
|
||||
//是否工作日
|
||||
let ymd = `${y}/${m}/${d}`;
|
||||
let formatDY = new Date(ymd.replace(/-/g, '/'));
|
||||
let week = formatDY.getDay();
|
||||
if (week == 0 || week == 6) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
isFutureDay(y, m, d) {
|
||||
//是否未来日期
|
||||
let ymd = `${y}/${m}/${d}`;
|
||||
let formatDY = new Date(ymd.replace(/-/g, '/'));
|
||||
let showTime = formatDY.getTime();
|
||||
let curTime = new Date().getTime();
|
||||
if (showTime > curTime) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// 标记日期
|
||||
isMarkDay(y, m, d) {
|
||||
let flag = false;
|
||||
for (let i = 0; i < this.markDays.length; i++) {
|
||||
let dy = `${y}-${m}-${d}`;
|
||||
if (this.markDays[i] == dy) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
},
|
||||
isToday(y, m, d) {
|
||||
let checkD = y + '-' + m + '-' + d;
|
||||
let today = this.getToday().date;
|
||||
if (checkD == today) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// 展开收起
|
||||
toggle() {
|
||||
this.monthOpen = !this.monthOpen;
|
||||
if (this.monthOpen) {
|
||||
this.positionTop = 0;
|
||||
} else {
|
||||
let index = -1;
|
||||
this.dates.forEach((i, x) => {
|
||||
this.isToday(i.year, i.month, i.date) && (index = x);
|
||||
});
|
||||
this.positionTop = -((Math.ceil((index + 1) / 7) || 1) - 1) * 80;
|
||||
}
|
||||
},
|
||||
// 点击回调
|
||||
selectOne(i, event) {
|
||||
let date = `${i.year}-${i.month}-${i.date}`;
|
||||
let selectD = new Date(date).getTime();
|
||||
let curTime = new Date().getTime();
|
||||
let week = new Date(date).getDay();
|
||||
let weekText = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
let formatWeek = '星期' + weekText[week];
|
||||
let response = {
|
||||
date: date,
|
||||
week: formatWeek
|
||||
};
|
||||
if (!i.isCurM) {
|
||||
// console.log('不在当前月范围内');
|
||||
return false;
|
||||
}
|
||||
if (selectD > curTime) {
|
||||
if (this.disabledAfter) {
|
||||
console.log('未来日期不可选');
|
||||
return false;
|
||||
} else {
|
||||
this.choose = date;
|
||||
this.$emit('onDayClick', response);
|
||||
}
|
||||
} else {
|
||||
this.choose = date;
|
||||
this.$emit('onDayClick', response);
|
||||
}
|
||||
console.log(response);
|
||||
},
|
||||
//改变年月
|
||||
changYearMonth(y, m) {
|
||||
this.dates = this.monthDay(y, m);
|
||||
this.y = y;
|
||||
this.m = m;
|
||||
},
|
||||
changeMonth(type) {
|
||||
let that = this
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
if (type == 'pre') {
|
||||
if (that.m + 1 == 2) {
|
||||
that.m = 12;
|
||||
that.y = that.y - 1;
|
||||
} else {
|
||||
that.m = that.m - 1;
|
||||
}
|
||||
that.month = this.$tools.getMonth(that.month, -1)
|
||||
that.$emit('onMonthClickPre', that.month)
|
||||
} else {
|
||||
if (this.m + 1 == 13) {
|
||||
this.m = 1;
|
||||
this.y = this.y + 1;
|
||||
} else {
|
||||
this.m = this.m + 1;
|
||||
}
|
||||
that.month = this.$tools.getMonth(that.month, +1)
|
||||
that.$emit('onMonthClickPre', that.month)
|
||||
}
|
||||
this.dates = this.monthDay(this.y, this.m);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.calendar-wrapper {
|
||||
color: #bbb7b7;
|
||||
border-radius: 10px;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
padding-bottom: 10rpx;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 88rpx;
|
||||
color: #42464A;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
justify-content: space-around;
|
||||
|
||||
.pre,
|
||||
.next {
|
||||
color: $btncolor;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.week {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.content0 {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: height 0.4s ease;
|
||||
|
||||
.days {
|
||||
transition: top 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
width: calc(100% / 7);
|
||||
|
||||
.day {
|
||||
font-style: normal;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 60rpx;
|
||||
|
||||
&.choose {
|
||||
background-color: $btncolor;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.nolm {
|
||||
color: #fff;
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
.isWorkDay {
|
||||
color: #42464a;
|
||||
}
|
||||
|
||||
.notSigned {
|
||||
font-style: normal;
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
background: #fa7268;
|
||||
border-radius: 10rpx;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.today {
|
||||
color: #fff;
|
||||
background-color: #a8c0ff;
|
||||
}
|
||||
|
||||
.workDay {
|
||||
font-style: normal;
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
background: #4d7df9;
|
||||
border-radius: 10rpx;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.markDay {
|
||||
font-style: normal;
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
background: #fa7268;
|
||||
border-radius: 10rpx;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hide {
|
||||
height: 80rpx !important;
|
||||
}
|
||||
|
||||
.weektoggle {
|
||||
width: 85rpx;
|
||||
height: 32rpx;
|
||||
position: relative;
|
||||
bottom: -42rpx;
|
||||
|
||||
&.down {
|
||||
transform: rotate(180deg);
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<view class="wrapper" v-if="isedit">
|
||||
<view class="bg" @click="onTap">
|
||||
<view class="edit" @click.stop>
|
||||
<view class="title">
|
||||
健康资料
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="editem">
|
||||
<view class="name">性别</view>
|
||||
<view class="radio mr-10" @click="selectsex(1)">
|
||||
<icon class="iconfont radioimg" :class="[info.sex==1?'icon-radio':'icon-kongradio']">
|
||||
</icon>
|
||||
<view class="ml-10">男</view>
|
||||
</view>
|
||||
<view class="radio" @click="selectsex(2)">
|
||||
<icon class="iconfont radioimg" :class="[info.sex==2?'icon-radio':'icon-kongradio']">
|
||||
</icon>
|
||||
<view class="ml-10">女</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="editem">
|
||||
<view class="name">身高</view>
|
||||
<view class="right">
|
||||
<input type="digit" v-model="info.height" placeholder="请输入身高" />cm
|
||||
</view>
|
||||
</view>
|
||||
<view class="editem">
|
||||
<view class="name">出生日期</view>
|
||||
<view class="right">
|
||||
<picker mode="date" :end="startDate" class="f-r" :value="info.birthday" @change="onBirthdayArr">
|
||||
<view class="uni-input">{{info.birthday?info.birthday:"请选择"}}
|
||||
<icon class="iconfont icon-arrow-down"></icon>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips">
|
||||
请准确填写信息方便我们给您更精确的报告
|
||||
</view>
|
||||
<view class="btn mt-15" @click="handleCloseClick">保存信息</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
info: {
|
||||
height: "",
|
||||
birthday: "",
|
||||
sex: 0,
|
||||
},
|
||||
ageArr: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isedit"]),
|
||||
userInfo: function() {
|
||||
return this.user
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
var agedata = []
|
||||
for (var i = 12; i <= 80; i++) {
|
||||
agedata.push(i);
|
||||
}
|
||||
this.ageArr = agedata
|
||||
this.info = this.user
|
||||
},
|
||||
methods: {
|
||||
onTap() {
|
||||
// this.isHeight = false
|
||||
// this.slideheight = this.userInfo.height
|
||||
// this.$store.commit("changeEdit", false);
|
||||
},
|
||||
// 性别切换
|
||||
selectsex(e) {
|
||||
this.info.sex = e
|
||||
},
|
||||
// 出生日期
|
||||
onBirthdayArr(e) {
|
||||
this.info.birthday = e.target.value
|
||||
},
|
||||
// 提交、
|
||||
handleCloseClick() {
|
||||
let that = this
|
||||
if (!that.info.sex) {
|
||||
that.$tools.msg("请选择性别")
|
||||
return
|
||||
}
|
||||
if (!that.info.height) {
|
||||
that.$tools.msg("请选择身高")
|
||||
return
|
||||
}
|
||||
if (!that.info.birthday) {
|
||||
that.$tools.msg("请选择出生日期")
|
||||
return
|
||||
}
|
||||
that.$store.commit("changeEdit", false);
|
||||
that.getResult()
|
||||
},
|
||||
getResult() {
|
||||
let that = this
|
||||
that.$model.getResult({
|
||||
birthday: that.userInfo.birthday,
|
||||
familyid: that.userInfo.familyid,
|
||||
height: that.userInfo.height,
|
||||
sex: that.userInfo.sex,
|
||||
}).then((res) => {
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.userInfo.familyid,
|
||||
})
|
||||
that.$store.dispatch("getFamilyList");
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<view v-if="isFirst" class="wrapper">
|
||||
<view class="bg" @click="onTap">
|
||||
<view class="edit" @click.stop>
|
||||
<view class="title">初始体重</view>
|
||||
<view class="editem" @click="hideKeyboard">
|
||||
<view class="name">日期</view>
|
||||
<view class="right">
|
||||
<picker mode="date" :value="user.firstresulttime" :end="endDate" @change="bindDateChange">
|
||||
<view class="text">{{regTime?regTime:user.firstresulttime?user.firstresulttime:"请选择"}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="editem">
|
||||
<view class="name">体重</view>
|
||||
<view class="right">
|
||||
<input v-model="weight" type="digit" placeholder="请输入体重" />kg
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn close" @click="onTap()">取消</view>
|
||||
<view class="btn" @click="handleTarget">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
regTime: "",
|
||||
weight: "",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isFirst"]),
|
||||
endDate() {
|
||||
return this.$tools.getDate("start")
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始体重
|
||||
handleTarget() {
|
||||
let that = this
|
||||
if (!that.regTime) {
|
||||
that.$tools.msg("请选择测量日期")
|
||||
return
|
||||
}
|
||||
if (!that.weight) {
|
||||
that.$tools.msg("请输入测量体重")
|
||||
return
|
||||
}
|
||||
that.$model.getfirstweight({
|
||||
familyid: that.user.familyid,
|
||||
time: that.regTime,
|
||||
weight: that.weight,
|
||||
}).then(res => {
|
||||
that.$tools.msg(res.message)
|
||||
if (res.code == 0) {
|
||||
that.$store.commit("changeFirst", false);
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.user.familyid,
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
//
|
||||
bindDateChange(e) {
|
||||
this.regTime = e.target.value
|
||||
},
|
||||
onTap() {
|
||||
this.regTime = ""
|
||||
this.weight = ""
|
||||
this.$store.commit("changeFirst", false);
|
||||
},
|
||||
hideKeyboard() {
|
||||
uni.hideKeyboard()
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.btn {
|
||||
width: 40%;
|
||||
float: right;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.edit {
|
||||
top: 20%
|
||||
}
|
||||
|
||||
.close {
|
||||
background: #dfdfdf !important;
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
<template>
|
||||
<view v-if="isRecord" class="wrapper">
|
||||
<view class="bg" @click="onTap">
|
||||
<view class="edit" @click.stop>
|
||||
<view class="title">手动记录</view>
|
||||
<view class="editem" @click="hideKeyboard">
|
||||
<view class="left">日期</view>
|
||||
<view class="right">
|
||||
<picker mode="date" :value="regTime" :end="endDate" @change="bindDateChange">
|
||||
<view class="text">{{regTime?regTime:"请选择"}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="editem">
|
||||
<view class="left">体重</view>
|
||||
<view class="right">
|
||||
<input v-model="weight" type="digit" placeholder="请输入体重" />kg
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn close" @click="onTap()">取消</view>
|
||||
<view class="btn" @click="handleTarget">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
regTime: "",
|
||||
weight: "",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isRecord"]),
|
||||
endDate() {
|
||||
return this.$tools.getDate("start")
|
||||
},
|
||||
startDate() {
|
||||
return this.$tools.GetDateStr(-90);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 手动记录
|
||||
handleTarget() {
|
||||
let that = this
|
||||
if (!that.regTime) {
|
||||
that.$tools.msg("请选择测量日期")
|
||||
return
|
||||
}
|
||||
if (!that.weight) {
|
||||
that.$tools.msg("请输入测量体重")
|
||||
return
|
||||
}
|
||||
that.$model.getinsertmeasure({
|
||||
familyid: that.user.familyid,
|
||||
time: that.regTime,
|
||||
weight: that.weight,
|
||||
}).then(res => {
|
||||
if (res.code != 0) return
|
||||
that.$tools.msg(res.message)
|
||||
that.$store.commit("changeRecord", false);
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: that.user.birthday,
|
||||
familyid: that.user.familyid,
|
||||
height: that.user.height,
|
||||
sex: that.user.sex,
|
||||
})
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.user.familyid,
|
||||
})
|
||||
that.$emit("getList", this.startDate, this.endDate)
|
||||
that.regTime = ""
|
||||
that.weight = ""
|
||||
})
|
||||
},
|
||||
//
|
||||
bindDateChange(e) {
|
||||
this.regTime = e.target.value
|
||||
},
|
||||
onTap() {
|
||||
this.regTime = ""
|
||||
this.weight = ""
|
||||
this.$store.commit("changeRecord", false);
|
||||
},
|
||||
hideKeyboard() {
|
||||
uni.hideKeyboard()
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.btn {
|
||||
width: 40%;
|
||||
float: right;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.edit {
|
||||
top: 20%
|
||||
}
|
||||
|
||||
.close {
|
||||
background: #dfdfdf !important;
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<view v-if="isTarget" class="wrapper">
|
||||
<view class="bg" @click="onTap">
|
||||
<view class="edit" @click.stop>
|
||||
<view class="title">目标体重</view>
|
||||
<view class="editem">
|
||||
<view class="left">目标体重</view>
|
||||
<view class="right">
|
||||
<input class="text" type="digit" placeholder="请输入目标体重" v-model="inputvalue" />kg
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn close" @click="onTap()">取消</view>
|
||||
<view class="btn" @click="handleWeight">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
inputvalue: "",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isTarget"]),
|
||||
startDate() {
|
||||
return this.$tools.getDate('start');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 目标体重
|
||||
handleWeight() {
|
||||
let that = this
|
||||
console.log("startDate", that.startDate)
|
||||
if (!that.inputvalue) {
|
||||
that.$tools.msg("请输入目标体重")
|
||||
return
|
||||
}
|
||||
that.$model.setTarget({
|
||||
familyid: that.user.familyid,
|
||||
time: that.startDate,
|
||||
weight: that.inputvalue,
|
||||
}).then(res => {
|
||||
if (res.code != 0) return
|
||||
that.$tools.msg(res.message)
|
||||
that.$store.commit("changeTarget", false);
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.user.familyid,
|
||||
})
|
||||
})
|
||||
},
|
||||
onTap() {
|
||||
this.inputvalue = ""
|
||||
this.$store.commit("changeTarget", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.btn {
|
||||
width: 40%;
|
||||
float: right;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.edit {
|
||||
top: 20%
|
||||
}
|
||||
|
||||
.close {
|
||||
background: #dfdfdf !important;
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<!--增加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,87 @@
|
|||
<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,
|
||||
};
|
||||
},
|
||||
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;
|
||||
const { width, height } = e.mp.detail;
|
||||
const recal = this.wxAutoImageCal(width, height);
|
||||
const { imageheight, imageWidth } = recal;
|
||||
const { padding, 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;`;
|
||||
},
|
||||
// 计算视觉优先的图片宽高
|
||||
wxAutoImageCal(originalWidth, originalHeight) {
|
||||
// 获取图片的原始长宽
|
||||
const { padding } = this.node.attr;
|
||||
// const windowWidth = this.node.$screen.width - (2 * padding);
|
||||
const windowWidth = this.node.$screen.width - 30;
|
||||
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,107 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--table类型-->
|
||||
<block v-else-if="node.tag == 'table'">
|
||||
<view :class="node.classStr" class="table" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate1';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate0',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<template>
|
||||
<view :class="(node.tag == 'li' ? node.classStr : (node.node==='text'?'text':''))">
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<!-- <view :class="node.classStr" :style="node.styleStr"> -->
|
||||
<view :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate2';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate1',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate11';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate10',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
{{node.text}}
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
{{node.text}}
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
{{node.text}}
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate11',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate3';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate2',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate4';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate3',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate5';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate4',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate6';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate5',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate7';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate6',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate8';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate7',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate9';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate8',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<view>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<block v-if="node.tag == 'button'">
|
||||
<button type="default" size="mini">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</button>
|
||||
</block>
|
||||
|
||||
<!--li类型-->
|
||||
<block v-else-if="node.tag == 'li'">
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--video类型-->
|
||||
<block v-else-if="node.tag == 'video'">
|
||||
<wx-parse-video :node="node" />
|
||||
</block>
|
||||
|
||||
<!--audio类型-->
|
||||
<block v-else-if="node.tag == 'audio'">
|
||||
<wx-parse-audio :node="node" />
|
||||
</block>
|
||||
|
||||
<!--img类型-->
|
||||
<block v-else-if="node.tag == 'img'">
|
||||
<wx-parse-img :node="node" />
|
||||
</block>
|
||||
|
||||
<!--a类型-->
|
||||
<block v-else-if="node.tag == 'a'">
|
||||
<view @click="wxParseATap" :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>
|
||||
</block>
|
||||
|
||||
<!--br类型-->
|
||||
<block v-else-if="node.tag == 'br'">
|
||||
<text>\n</text>
|
||||
</block>
|
||||
|
||||
<!--其他标签-->
|
||||
<block v-else>
|
||||
<view :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>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate10';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate9',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(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);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<!--增加video标签支持,并循环添加-->
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<video :class="node.classStr" 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,195 @@
|
|||
// 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, ' ');
|
||||
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(/ /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 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,102 @@
|
|||
## uParse 适用于 uni-app/mpvue 的富文本解析组件
|
||||
|
||||
> 支持 Html、Markdown 解析,Fork自: [mpvue-wxParse](https://github.com/F-loat/mpvue-wxParse)
|
||||
|
||||
|
||||
## 属性
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| -----------------|--------------- | ------------- | ---------------- |
|
||||
| loading | Boolean | false | 数据加载状态 |
|
||||
| className | String | — | 自定义 class 名称 |
|
||||
| content | String | — | 渲染内容 |
|
||||
| noData | String | 数据不能为空 | 空数据时的渲染展示 |
|
||||
| startHandler | Function | 见源码 | 自定义 parser 函数 |
|
||||
| endHandler | Function | null | 自定义 parser 函数 |
|
||||
| charsHandler | Function | null | 自定义 parser 函数 |
|
||||
| imageProp | Object | 见下文 | 图片相关参数 |
|
||||
|
||||
### 自定义 parser 函数具体介绍
|
||||
|
||||
* 传入的参数为当前节点 `node` 对象及解析结果 `results` 对象,例如 `startHandler(node, results)`
|
||||
* 无需返回值,通过对传入的参数直接操作来完成需要的改动
|
||||
* 自定义函数会在原解析函数处理之后执行
|
||||
|
||||
### imageProp 对象具体属性
|
||||
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| -----------------|--------------- | ------------- | ------------------ |
|
||||
| mode | String | 'aspectFit' | 图片裁剪、缩放的模式 |
|
||||
| padding | Number | 0 | 图片内边距 |
|
||||
| lazyLoad | Boolean | false | 图片懒加载 |
|
||||
| domain | String | '' | 图片服务域名 |
|
||||
|
||||
## 事件
|
||||
|
||||
| 名称 | 参数 | 描述 |
|
||||
| -----------------|----------------- | ---------------- |
|
||||
| preview | 图片地址,原始事件 | 预览图片时触发 |
|
||||
| navigate | 链接地址,原始事件 | 点击链接时触发 |
|
||||
|
||||
## 基本使用方法
|
||||
|
||||
|
||||
``` vue
|
||||
<template>
|
||||
<div>
|
||||
<u-parse :content="article" @preview="preview" @navigate="navigate" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uParse from '@/components/u-parse/u-parse.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
uParse
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
article: '<div>我是HTML代码</div>'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
preview(src, e) {
|
||||
// do something
|
||||
},
|
||||
navigate(href, e) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url("@/components/u-parse/u-parse.css");
|
||||
</style>
|
||||
```
|
||||
|
||||
|
||||
## 渲染 Markdown
|
||||
|
||||
> 先将 markdown 转换为 html 即可
|
||||
|
||||
```
|
||||
npm install marked
|
||||
```
|
||||
|
||||
``` js
|
||||
import marked from 'marked'
|
||||
import uParse from '@/components/u-parse/u-parse.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
uParse
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
article: marked(`#hello, markdown!`)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
.wxParse {
|
||||
width: 100%;
|
||||
font-family: Helvetica, sans-serif;
|
||||
font-size: 30upx;
|
||||
color: #666;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.wxParse view {
|
||||
word-break: hyphenate;
|
||||
}
|
||||
|
||||
.wxParse .inline {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wxParse .div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wxParse .h1 .text {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
.wxParse .h2 .text {
|
||||
font-size: 1.5em;
|
||||
margin: 0.83em 0;
|
||||
}
|
||||
.wxParse .h3 .text {
|
||||
font-size: 1.17em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
.wxParse .h4 .text {
|
||||
margin: 1.33em 0;
|
||||
}
|
||||
.wxParse .h5 .text {
|
||||
font-size: 0.83em;
|
||||
margin: 1.67em 0;
|
||||
}
|
||||
.wxParse .h6 .text {
|
||||
font-size: 0.67em;
|
||||
margin: 2.33em 0;
|
||||
}
|
||||
|
||||
.wxParse .h1 .text,
|
||||
.wxParse .h2 .text,
|
||||
.wxParse .h3 .text,
|
||||
.wxParse .h4 .text,
|
||||
.wxParse .h5 .text,
|
||||
.wxParse .h6 .text,
|
||||
.wxParse .b,
|
||||
.wxParse .strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
|
||||
.wxParse .p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.wxParse .i,
|
||||
.wxParse .cite,
|
||||
.wxParse .em,
|
||||
.wxParse .var,
|
||||
.wxParse .address {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
.wxParse .code {
|
||||
display: inline;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.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 .s {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.wxParse .a {
|
||||
color: deepskyblue;
|
||||
}
|
||||
|
||||
.wxParse .video {
|
||||
text-align: center;
|
||||
margin: 22upx 0;
|
||||
}
|
||||
|
||||
.wxParse .video-video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wxParse .img {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
max-width: 100%;
|
||||
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: 33upx;
|
||||
}
|
||||
.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 .table {
|
||||
width: 100%;
|
||||
}
|
||||
.wxParse .thead, .wxParse .tfoot, .wxParse .tr {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.wxParse .tr {
|
||||
width:100%;
|
||||
display: flex;
|
||||
border-right: 2upx solid #e0e0e0;
|
||||
border-bottom: 2upx solid #e0e0e0;
|
||||
}
|
||||
.wxParse .th,
|
||||
.wxParse .td {
|
||||
display: flex;
|
||||
width: 1276upx;
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
padding: 11upx;
|
||||
border-left: 2upx solid #e0e0e0;
|
||||
}
|
||||
.wxParse .td:last {
|
||||
border-top: 2upx solid #e0e0e0;
|
||||
}
|
||||
.wxParse .th {
|
||||
background: #f0f0f0;
|
||||
border-top: 2upx solid #e0e0e0;
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
<!--**
|
||||
* forked from:https://github.com/F-loat/mpvue-wxParse
|
||||
*
|
||||
* github地址: https://github.com/dcloudio/uParse
|
||||
*
|
||||
* for: uni-app框架下 富文本解析
|
||||
*/-->
|
||||
|
||||
<template>
|
||||
<!--基础元素-->
|
||||
<div class="wxParse" :class="className" v-if="!loading">
|
||||
<block v-for="(node,index) of nodes" :key="index">
|
||||
<wxParseTemplate :node="node" />
|
||||
</block>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HtmlToJson from './libs/html2json';
|
||||
import wxParseTemplate from './components/wxParseTemplate0';
|
||||
|
||||
export default {
|
||||
name: 'wxParse',
|
||||
props: {
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
noData: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
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 {
|
||||
imageUrls: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
nodes() {
|
||||
const {
|
||||
content,
|
||||
noData,
|
||||
imageProp,
|
||||
startHandler,
|
||||
endHandler,
|
||||
charsHandler,
|
||||
} = this;
|
||||
const parseData = content || noData;
|
||||
const customHandler = {
|
||||
start: startHandler,
|
||||
end: endHandler,
|
||||
chars: charsHandler,
|
||||
};
|
||||
const results = HtmlToJson(parseData, customHandler, imageProp, this);
|
||||
this.imageUrls = results.imageUrls;
|
||||
console.log(results)
|
||||
return results.nodes;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
navigate(href, $event) {
|
||||
this.$emit('navigate', href, $event);
|
||||
},
|
||||
preview(src, $event) {
|
||||
if (!this.imageUrls.length) return;
|
||||
wx.previewImage({
|
||||
current: src,
|
||||
urls: this.imageUrls,
|
||||
});
|
||||
this.$emit('preview', src, $event);
|
||||
},
|
||||
removeImageUrl(src) {
|
||||
const { imageUrls } = this;
|
||||
imageUrls.splice(imageUrls.indexOf(src), 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<view class="wrapper" v-if="isLogin">
|
||||
<view class="popup" @click="onTap">
|
||||
<view class="block" @click.stop>
|
||||
<view class="item" @click="getUserInfo">
|
||||
<image src="../static/2253.png" class="image1"></image>
|
||||
<view class="text">
|
||||
<view><text></text>体重体脂测量与记录</view>
|
||||
<view><text></text>18项身体数据分析、身体评分</view>
|
||||
<view><text></text>满足所有人群检测</view>
|
||||
</view>
|
||||
<view class="pbtn">立即体验</view>
|
||||
</view>
|
||||
<icon class="t-icon t-icon-quxiao image2" @click="onTap"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapState(["user", "isLogin"]),
|
||||
},
|
||||
methods: {
|
||||
onTap() {
|
||||
this.$store.commit("changeUserLogin", false);
|
||||
},
|
||||
getUserInfo() {
|
||||
let that = this
|
||||
uni.getUserProfile({
|
||||
desc: '登录',
|
||||
success: (infoRes) => {
|
||||
console.log("getUserProfile授权成功", infoRes, that.url);
|
||||
uni.redirectTo({
|
||||
url: `/pageTwo/login/login?name=` + infoRes.userInfo.nickName +
|
||||
"&headimg=" + infoRes.userInfo.avatarUrl + "&url=" + that.url
|
||||
})
|
||||
// that.DecodeEncryptedData(infoRes)
|
||||
that.$store.commit("changeUserLogin", false);
|
||||
},
|
||||
fail: (res) => {
|
||||
console.log("授权失败", res)
|
||||
}
|
||||
});
|
||||
},
|
||||
// 解密
|
||||
DecodeEncryptedData(data) {
|
||||
let that = this
|
||||
that.$model.getDecryptdata({
|
||||
encryptedData: data.encryptedData,
|
||||
iv: data.iv,
|
||||
tenantid: uni.getStorageSync('tenantid'),
|
||||
sessionid: uni.getStorageSync('sessionid'),
|
||||
}).then(res => {
|
||||
if (res.code != 0) return
|
||||
uni.redirectTo({
|
||||
url: `/pageTwo/login/login`
|
||||
})
|
||||
console.log("解密成功", res)
|
||||
}).catch(e => {
|
||||
console.log("解密失败", e)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.popup {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 291px;
|
||||
height: 324px;
|
||||
position: relative;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin: auto;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
border-radius: 15px;
|
||||
|
||||
text {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: $greencolor;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.image1 {
|
||||
width: 291px;
|
||||
height: 324px;
|
||||
}
|
||||
|
||||
.text {
|
||||
position: absolute;
|
||||
top: 60%;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
line-height: 28px;
|
||||
right: 10px;
|
||||
left: 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.pbtn {
|
||||
background: $btncolor;
|
||||
text-align: center;
|
||||
border-radius: 10px;
|
||||
margin: 5px auto;
|
||||
width: 50%;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.image2 {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 30px;
|
||||
color: #666;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 20px auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import './uni.scss';
|
||||
import './assets/common.scss'
|
||||
import './assets/iconfont-weapp-icon.css'
|
||||
import './assets/iconfont.css'
|
||||
import store from './store'
|
||||
Vue.prototype.$store = store;
|
||||
// js
|
||||
import tools from '@/tools/tools.js'
|
||||
Vue.prototype.$tools = tools;
|
||||
// json
|
||||
import data4 from '@/tools/data4.js'
|
||||
Vue.prototype.weightInfo = data4;
|
||||
//请求
|
||||
import http from '@/tools/https.js'
|
||||
Vue.prototype.$http = http;
|
||||
//接口
|
||||
import model from '@/tools/model.js'
|
||||
Vue.prototype.$model = model;
|
||||
|
||||
Vue.config.productionTip = false
|
||||
App.mpType = 'app'
|
||||
//让页面onLoad在onLaunch后执行
|
||||
Vue.prototype.$onLaunched = new Promise(resolve => {
|
||||
Vue.prototype.$isResolve = resolve
|
||||
})
|
||||
const app = new Vue({
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"name" : "每日一称成人",
|
||||
"appid" : "__UNI__1EBB7E8",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"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\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "wx3e83b37ba682faf5",
|
||||
"setting" : {
|
||||
"urlCheck" : true,
|
||||
"minified" : true,
|
||||
"es6" : true,
|
||||
"postcss" : true
|
||||
},
|
||||
"usingComponents" : true,
|
||||
// 开启分包优化
|
||||
"optimization" : {
|
||||
"Package8s" : true
|
||||
},
|
||||
"plugins" : {
|
||||
"sdkPlugin" : {
|
||||
//这里是引用的插件名称 地图路线规划
|
||||
"version" : "2.1.0", //插件版本
|
||||
"provider" : "wx17e93aad47cdae1a" //插件appid
|
||||
}
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
<template>
|
||||
<view class="content pkconp">
|
||||
<view class="header">
|
||||
<view class="left">
|
||||
<image :src="memInfo.headimg" class="image1"></image>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="name">{{memInfo.name?memInfo.name:memInfo.nickname}}</view>
|
||||
<view class="top">
|
||||
<view class="age">性别:{{memInfo.sex==0?'未知':memInfo.sex==1?'男':'女'}}</view>
|
||||
<view>年龄:{{user.age}}岁</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <button class="pkclass" @click="handleImage">保存图片</button> -->
|
||||
</view>
|
||||
<view class="box">
|
||||
<view class="item">
|
||||
<view>{{memInfo.day?memInfo.day:'0'}}</view>
|
||||
<text>时间(天)</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>{{Math.abs(memInfo.weightdiff)}}</view>
|
||||
<text v-if="Number(memInfo.weightdiff)>0">增重(kg)</text>
|
||||
<text v-else>减重(kg)</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>{{Math.abs(memInfo.fat_wdiff)}}</view>
|
||||
<text v-if="Number(memInfo.fat_wdiff)>0">增脂(kg)</text>
|
||||
<text v-else>减脂(kg)</text>
|
||||
</view>
|
||||
<view class="time">
|
||||
<view>
|
||||
<icon class="yuanxing"></icon>{{memInfo.time}}
|
||||
</view>数据变化
|
||||
</view>
|
||||
</view>
|
||||
<view class="control">
|
||||
<!-- 名称 -->
|
||||
<view class="title">
|
||||
<view class="name"></view>
|
||||
<view>趋势</view>
|
||||
<view>之前</view>
|
||||
<view>之后</view>
|
||||
</view>
|
||||
<view v-for="(ite,ind) in listStr" :key="ind" class="li">
|
||||
<view class="name">
|
||||
<view class="icon">
|
||||
<icon class="t-icon" :class="'t-icon-'+ite.key"></icon>
|
||||
</view>
|
||||
<text>{{ite.title}}</text>
|
||||
</view>
|
||||
<view class="num" v-if="ite.title=='体型'||ite.title=='肥胖等级'">
|
||||
<icon class="t-icon t-icon-hengxian"></icon>
|
||||
</view>
|
||||
<view class="num" v-else>
|
||||
{{ite.num}}
|
||||
<icon class="t-icon t-icon-shang" v-if="ite.vs=='1'"></icon>
|
||||
<icon class="t-icon t-icon-xia" v-if="ite.vs=='-1'"></icon>
|
||||
<icon class="t-icon t-icon-hengxian" v-if="!ite.vs||ite.vs=='0'||ite.num=='0.00'"></icon>
|
||||
</view>
|
||||
<view class="f0" v-if="ite.title=='体型'||ite.title=='肥胖等级'">
|
||||
<text>{{ite.fevaluation}}</text>
|
||||
</view>
|
||||
<view class="f" v-else>
|
||||
<view>{{ite.fvalue}}</view>
|
||||
<text v-if="ite.fevaluation">{{ite.fevaluation}}</text>
|
||||
</view>
|
||||
<view class="f0" v-if="ite.title=='体型'||ite.title=='肥胖等级'">
|
||||
<text>{{ite.sevaluation}}</text>
|
||||
</view>
|
||||
<view class="f" v-else>
|
||||
<view>{{ite.svalue}}</view>
|
||||
<text v-if="ite.fevaluation">{{ite.sevaluation}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
|
||||
export default {
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
console.log("options", options)
|
||||
if (options.info) {
|
||||
that.infoID = JSON.parse(options.info)
|
||||
that.handleSharepic(that.infoID)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
},
|
||||
methods: {
|
||||
handleSharepic(id) {
|
||||
let that = this
|
||||
that.$model.getresultdiff({
|
||||
familyid: id.familyid,
|
||||
firstId: id.firstId,
|
||||
secondId: id.secondId,
|
||||
}).then(res => {
|
||||
console.log("res", res)
|
||||
if (res.code != 0) {
|
||||
this.$tools.msg(res.message)
|
||||
return
|
||||
}
|
||||
that.handleInfoList(res.data)
|
||||
})
|
||||
},
|
||||
handleInfoList(data) {
|
||||
let that = this
|
||||
that.memInfo = data
|
||||
let listStr = that.weightInfo.infoList(data.firstresult)
|
||||
let str = that.memInfo.secondresult
|
||||
for (var i = 0; i < listStr.length; i++) {
|
||||
listStr[i].svalue = str[listStr[i].key];
|
||||
let num = listStr[i].svalue - listStr[i].fvalue
|
||||
if (num < 0) {
|
||||
listStr[i].vs = '-1'
|
||||
} else if (num > 0) {
|
||||
listStr[i].vs = '1'
|
||||
} else {
|
||||
listStr[i].vs = '0'
|
||||
}
|
||||
listStr[i].num = Math.abs(num).toFixed(2)
|
||||
if (str[listStr[i].level]) {
|
||||
listStr[i].sevaluation = str[listStr[i].level];
|
||||
}
|
||||
console.log("listStr[i].title", listStr[i].title)
|
||||
// if (listStr[i].title == "体重") {
|
||||
// if (listStr[i].svalue > Number(str.standardweight)) {
|
||||
// listStr[i].sevaluation = "偏高"
|
||||
// } else if (listStr[i].svalue < Number(str.standardweight)) {
|
||||
// listStr[i].sevaluation = "偏低"
|
||||
// } else {
|
||||
// listStr[i][i].sevaluation = "标准"
|
||||
// }
|
||||
// }
|
||||
}
|
||||
that.listStr = listStr
|
||||
console.log("listStr[i]", that.memInfo, listStr)
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
infoID: {},
|
||||
memInfo: {},
|
||||
listStr: [],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.age {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
padding: 3px;
|
||||
margin-right: 7px;
|
||||
background-color: #aaa;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.t-icon-hengxian {
|
||||
height: 4px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
<template>
|
||||
<view class="common homePage">
|
||||
<!-- 头部 -->
|
||||
<headTop :token="token"></headTop>
|
||||
<!-- 健康报告 -->
|
||||
<view class="myinfo myinfoPage">
|
||||
<view class="mt-15" v-show="MeasureResult&&MeasureResult.muscle==0">
|
||||
<view class="unusual">体脂测量异常,请重新测量</view>
|
||||
</view>
|
||||
<view v-if="infoList.length">
|
||||
<view class="box">
|
||||
<view class="left">
|
||||
<text class="text">本次健康评分</text>
|
||||
<view class="circleprogress">
|
||||
<view class="wrapper">
|
||||
<view class="leftprogress" :style="{ width: MeasureResult.cmi + '%'}">
|
||||
</view>
|
||||
</view>
|
||||
<view class="fen">
|
||||
<view>{{MeasureResult.cmi}}</view>分
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="item">
|
||||
<view><text>{{MeasureResult.height}}</text>cm</view>
|
||||
<view class="tivon">身高</image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view><text>{{MeasureResult.weight}}</text>kg</view>
|
||||
<view>体重</view>
|
||||
</view>
|
||||
<!-- <view class="item">
|
||||
<view><text>{{MeasureResult.lbm}}</text>kg</view>
|
||||
<view class="tivon">去脂体重</image>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="item">
|
||||
<view><text>{{MeasureResult.bodyage}}</text>岁</view>
|
||||
<view>体龄</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view><text class="f-14">{{MeasureResult.body}}</text></view>
|
||||
<view>体型</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="box1">
|
||||
<view class="h2">
|
||||
<icon class="yuanxing"></icon>其他人体成分分析
|
||||
</view>
|
||||
<view class="list" v-for="(item,index) in infoList" :key="index" @click="handleToggle(index)">
|
||||
<view class="block">
|
||||
<view class="name">
|
||||
<icon class="t-icon iconfont" :class="'t-icon-'+item.key"></icon>
|
||||
{{item.title}}
|
||||
</view>
|
||||
<view class="val" v-if="item.title!='肥胖等级'">
|
||||
{{item.fvalue?item.fvalue:'0'}}{{item.dw}}
|
||||
</view>
|
||||
<view class="val0" v-else>{{item.fevaluation}}</view>
|
||||
<view class="level" v-if="item.title!='肥胖等级'">
|
||||
<view class="btnf" :style="{backgroundColor:item.color}">{{item.fevaluation}}</view>
|
||||
</view>
|
||||
<view class="icon">
|
||||
<icon class="iconfont icon-arrow-down" v-if="item.desc"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="desc" v-if="item.showCon">
|
||||
<view v-if="item.desc">{{item.desc}}</view>
|
||||
<view class="statuevue" v-if="item.slist">
|
||||
<view class="bi" v-if="item.title!='基础代谢'">
|
||||
<view class="item" v-for="(ite , ind) in item.slist" :key="ind"
|
||||
:style="{backgroundColor:ite.color}">
|
||||
<view class="span1">{{ite.text}}</view>
|
||||
<view v-if="ite.text==item.fevaluation&&item.fvalue>ite.maxvalue"
|
||||
style="right: 10px" class="peobox">
|
||||
<view class="xx"></view>
|
||||
</view>
|
||||
<view v-if="ite.text==item.fevaluation&&item.fvalue<=ite.maxvalue"
|
||||
:style="'left:'+item.leftval+'rem'" class="peobox">
|
||||
<view class="xx"></view>
|
||||
</view>
|
||||
<view class="span" v-if="ind<item.slist.length-1">{{ite.maxvalue}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="kcalClass">
|
||||
标准值:{{item.slist[0].maxvalue}}kcal
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="introction">
|
||||
<icon class="t-icon t-icon-tishi"></icon>
|
||||
<span>此测量数据仅供参考,不可代替医学专业测试!</span>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="nolist">
|
||||
<icon class="iconfont icon-zanwu"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
import headTop from "@/components/header/head.vue"
|
||||
export default {
|
||||
components: {
|
||||
headTop
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
devtype: 0,
|
||||
infoList: [],
|
||||
deviceId: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "MeasureResult"]),
|
||||
},
|
||||
onUnload: function() {
|
||||
let that = this
|
||||
uni.switchTab({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
},
|
||||
onShow() {
|
||||
let that = this;
|
||||
that.token = uni.getStorageSync('token')
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
console.log("报告页监听蓝牙状态openBluetoothAdapter", res.available)
|
||||
})
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this;
|
||||
console.log("options", options)
|
||||
if (options) {
|
||||
that.devtype = options.t
|
||||
that.deviceId = options.sn
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
that.handleToggle(0)
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
MeasureResult() {
|
||||
this.handleToggle(0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 切换
|
||||
handleToggle(index) {
|
||||
let that = this
|
||||
if (!that.MeasureResult) return
|
||||
let str = this.weightInfo.infoList(that.MeasureResult).slice(1, 14)
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (i == index) {
|
||||
str[i].showCon = !str[i].showCon
|
||||
} else {
|
||||
str[i].showCon = false
|
||||
}
|
||||
}
|
||||
that.infoList = this.weightInfo.infoList(that.MeasureResult).slice(1, 14)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.myinfo {
|
||||
margin-top: 105px;
|
||||
}
|
||||
|
||||
.val0 {
|
||||
position: absolute;
|
||||
left: 40%;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
z-index: 9 !important;
|
||||
}
|
||||
|
||||
.unusual {
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
color: #e83a1e;
|
||||
margin: 15px;
|
||||
background: #f7e4c8;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.introction {
|
||||
display: flex;
|
||||
margin-left: 15px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
|
||||
.t-icon {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-right: 5px;
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view>
|
||||
<view class="title">{{content.title}}</view>
|
||||
<view class="time">发布时间:{{content.createtime}}</view>
|
||||
<u-parse :content="content.content" @preview="preview" @navigate="navigate"></u-parse>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uParse from '@/components/u-parse/u-parse.vue'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
content: "",
|
||||
url: null
|
||||
}
|
||||
},
|
||||
components: {
|
||||
uParse
|
||||
},
|
||||
onLoad(option) {
|
||||
console.log(option)
|
||||
if (option.id) {
|
||||
this.getOrderDetail(option.id);
|
||||
}
|
||||
if (option.url) {
|
||||
this.url = option.url
|
||||
} else {
|
||||
this.url = null
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
getOrderDetail(orderno) {
|
||||
this.$model.GetAdListDetail({
|
||||
id: orderno
|
||||
}).then(res => {
|
||||
if (res.code != 0) return
|
||||
this.content = res.data
|
||||
console.log("资讯详情", res)
|
||||
});
|
||||
},
|
||||
preview(src, e) {
|
||||
// do something
|
||||
},
|
||||
navigate(href, e) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import url("@/components/u-parse/u-parse.css");
|
||||
|
||||
.content {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
text-align: left;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.time {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
margin-bottom: 15px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class="top">
|
||||
<image src="@/static/logo.png"></image>
|
||||
<text>每日一称-成人</text>
|
||||
</view>
|
||||
<view class="edit">
|
||||
<view class="ts">
|
||||
<view>短信验证码登录</view>
|
||||
</view>
|
||||
<view class="editem">
|
||||
<view class="input">
|
||||
<input class="uni-input" v-model="phone" placeholder="请输入手机号" />
|
||||
</view>
|
||||
<view class="input yanzheng">
|
||||
<view class="yanzhengma">
|
||||
<input class="uni-input" v-model="code" placeholder="请输入验证码" />
|
||||
</view>
|
||||
<button class="code" type="none" @tap="handleCode" v-model="codeInfo"
|
||||
:disabled="disabled">{{second<60 ? second+'S后重发':'获取验证码'}}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btnlogin" @click="handleTelLogin">登录</view>
|
||||
</view>
|
||||
<view class="btnGroup">
|
||||
<view class="wxbtn" v-if="iswxphone">
|
||||
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
|
||||
<icon class="iconfont icon-weixin"></icon>
|
||||
<text>微信登录</text>
|
||||
</button>
|
||||
</view>
|
||||
<view class="xieyi">
|
||||
<checkbox-group @change="checkboxChange" class="group">
|
||||
<checkbox :value="1" checked="true" style="transform:scale(0.7)" />同意每日一称<text
|
||||
@click="handlexieyi">《个人信息保护政策》</text>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
phone: "",
|
||||
code: "",
|
||||
disabled: false,
|
||||
second: 60,
|
||||
value: 1,
|
||||
iswxphone: true,
|
||||
infoRes: {}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
if (options) {
|
||||
that.infoRes = options
|
||||
console.log("登录信息", options, that.infoRes)
|
||||
}
|
||||
|
||||
this.iswxphone = uni.getStorageSync('iswxphone')
|
||||
},
|
||||
methods: {
|
||||
checkboxChange(e) {
|
||||
this.value = e.detail.value.length ? e.detail.value[0] : "0"
|
||||
},
|
||||
// 登录、
|
||||
handleTelLogin() {
|
||||
let that = this
|
||||
if (this.value == 0) {
|
||||
that.$tools.msg("请先勾选同意每日一称《个人信息保护政策》")
|
||||
return
|
||||
}
|
||||
if (!this.phone) {
|
||||
that.$tools.msg("请输入手机号")
|
||||
return
|
||||
}
|
||||
if (!(/^1[3456789]\d{9}$/.test(that.phone))) {
|
||||
that.$tools.msg("请输入正确的手机号码")
|
||||
return
|
||||
}
|
||||
if (!that.code) {
|
||||
that.$tools.msg("请输入验证码")
|
||||
return
|
||||
}
|
||||
this.$model.getRegister({
|
||||
phone: that.phone,
|
||||
tenantId: uni.getStorageSync('tenantid'),
|
||||
sessionId: uni.getStorageSync('sessionid'),
|
||||
name: that.infoRes.name,
|
||||
headImg: that.infoRes.headimg,
|
||||
code: that.code,
|
||||
isvrcode: true,
|
||||
}).then(res => {
|
||||
if (res.code != 0) {
|
||||
that.$tools.msg(res.message)
|
||||
return
|
||||
}
|
||||
uni.setStorageSync('token', res.data.token)
|
||||
uni.setStorageSync('iswxphone', res.data.iswxphone)
|
||||
uni.setStorageSync('refreshtoken', res.data.refreshtoken)
|
||||
uni.setStorageSync('sessionid', res.data.sessionid)
|
||||
if (that.infoRes.url == 'active') {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/active"
|
||||
})
|
||||
} else {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}
|
||||
}).catch(err => {})
|
||||
},
|
||||
// 获取验证码
|
||||
handleCode() {
|
||||
let that = this
|
||||
if (!that.phone) {
|
||||
that.$tools.msg("请输入手机号")
|
||||
return
|
||||
}
|
||||
if (!(/^1[3456789]\d{9}$/.test(that.phone))) {
|
||||
that.$tools.msg("请输入正确的手机号码")
|
||||
return
|
||||
}
|
||||
//
|
||||
that.$model.getSendCode({
|
||||
phone: that.phone
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
if (res.code != 0) {
|
||||
that.$tools.msg(res.message)
|
||||
return
|
||||
}
|
||||
that.disabled = true
|
||||
let interval = setInterval(() => {
|
||||
--that.second
|
||||
}, 1000)
|
||||
setTimeout(() => {
|
||||
clearInterval(interval)
|
||||
that.disabled = false
|
||||
that.second = 60
|
||||
}, 60000)
|
||||
}).catch(err => {})
|
||||
},
|
||||
// 授权
|
||||
getPhoneNumber(res) {
|
||||
const that = this
|
||||
if (this.value == 0) {
|
||||
that.$tools.msg("请先勾选同意每日一称《个人信息保护政策")
|
||||
return
|
||||
}
|
||||
if (res.detail.errMsg == 'getPhoneNumber:ok') {
|
||||
console.log("res", res)
|
||||
this.$model.getregister({
|
||||
tenantId: uni.getStorageSync('tenantid'),
|
||||
sessionId: uni.getStorageSync('sessionid'),
|
||||
encryptedData: res.detail.encryptedData,
|
||||
iv: res.detail.iv,
|
||||
name: that.infoRes.name,
|
||||
headImg: that.infoRes.headimg,
|
||||
fansid: uni.getStorageSync('fansid')
|
||||
}).then(res => {
|
||||
if (res.code != 0) return
|
||||
that.value = 1
|
||||
uni.setStorageSync('token', res.data.token)
|
||||
uni.setStorageSync('iswxphone', res.data.iswxphone)
|
||||
uni.setStorageSync('refreshtoken', res.data.refreshtoken)
|
||||
uni.setStorageSync('sessionid', res.data.sessionid)
|
||||
if (that.infoRes.url == 'active') {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/active"
|
||||
})
|
||||
} else {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
//
|
||||
handlexieyi() {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/login/detail?id=08DA1796-2FEE-4813-8B0C-8A45E7A57E70"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.top {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80px 0 0;
|
||||
|
||||
image {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin: auto;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
text {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.edit {
|
||||
width: 75%;
|
||||
height: auto;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
margin: 40px auto 15px;
|
||||
|
||||
.ts {
|
||||
text-align: left;
|
||||
margin-bottom: 10px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.editem {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28upx;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
border: #dfdfdf 1px solid;
|
||||
padding: 0 10px;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.btnlogin {
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
background: $btncolor;
|
||||
font-weight: 700;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.code {
|
||||
width: 110px;
|
||||
background: #dfdfdf;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
right: 2.5px;
|
||||
top: 2.5px;
|
||||
}
|
||||
}
|
||||
|
||||
.btnGroup {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
background-color: inherit;
|
||||
line-height: inherit;
|
||||
position: absolute;
|
||||
bottom: 80rpx;
|
||||
|
||||
.wxbtn {
|
||||
width: 100%;
|
||||
|
||||
icon {
|
||||
font-size: 25px;
|
||||
color: #28c445;
|
||||
}
|
||||
|
||||
text {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button {
|
||||
line-height: initial;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
button::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.xieyi {
|
||||
font-size: 14px;
|
||||
margin-top: 20px;
|
||||
color: #333;
|
||||
|
||||
text {
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
<template>
|
||||
<view class="box">
|
||||
<view class="lanBox">
|
||||
<form action>
|
||||
<view class="headbox">
|
||||
<view class="touxiang">
|
||||
<icon class="t-icon t-icon-touxiang headimage"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan2">
|
||||
请补充信息,帮助我们更准确的分析数据
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">用户名/昵称</view>
|
||||
<view class="right">
|
||||
<input name="name" type="text" v-model="name" placeholder="请输入用户名/昵称" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">性别</view>
|
||||
<view class="right">
|
||||
<picker mode="selector" :range="sexItem" @change="onsexArr">
|
||||
<view class="uni-input">{{sex==0?'请选择':sex==1?'男':'女'}}</view>
|
||||
<icon class="iconfont icon-arrow-down"></icon>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">身高</view>
|
||||
<view class="right">
|
||||
<input type="digit" class="mr-5" v-model="height" placeholder="请输入身高" />cm
|
||||
<!-- <view class="uni-input">{{height?height+"cm":"请选择"}}</view>
|
||||
<icon class="iconfont icon-arrow-down ml-15"></icon> -->
|
||||
<!-- <picker mode="selector" class="f-r" value="85" :range="heightArr" @change="onheightArr">
|
||||
<view class="uni-input">{{height!=0?height:"请选择"}}</view>
|
||||
<icon class="iconfont icon-arrow-down"></icon>
|
||||
</picker> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">出生日期</view>
|
||||
<view class="right">
|
||||
<picker class="picker" mode="date" :end="startDate" :value="birthday" @change="bindDateChange">
|
||||
<view class="uni-input">{{birthday?birthday:"请选择"}}</view>
|
||||
<icon class="iconfont icon-arrow-down"></icon>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
<view v-if="isHeight" class="slidePopup">
|
||||
<view class="bg" @click="onTap">
|
||||
<view class="slide-box" @click.stop>
|
||||
<view class="btnGroup">
|
||||
<view class="subtn close" @click="onTap">取消</view>
|
||||
<view class="heightVal">{{height}}cm</view>
|
||||
<view class="subtn" @click="isHeight = false">确定</view>
|
||||
</view>
|
||||
<slide-choose v-model="height" ref="slide"></slide-choose>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn" @click="confirmInfo">提交</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ageArr: [],
|
||||
sexItem: [
|
||||
"男",
|
||||
"女"
|
||||
],
|
||||
sex: 0,
|
||||
name: null,
|
||||
birthday: "",
|
||||
height: "",
|
||||
isHeight: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
userInfo() {
|
||||
return this.user
|
||||
},
|
||||
startDate() {
|
||||
return this.$tools.getDate('start');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 提交
|
||||
confirmInfo() {
|
||||
let data = {};
|
||||
if (!this.name) {
|
||||
this.$tools.msg("请输入用户名")
|
||||
return;
|
||||
}
|
||||
if (!this.sex) {
|
||||
this.$tools.msg("请选择性别")
|
||||
return;
|
||||
}
|
||||
if (!this.height) {
|
||||
this.$tools.msg("请选择身高")
|
||||
return;
|
||||
}
|
||||
if (!this.birthday) {
|
||||
this.$tools.msg("请选择出生日期")
|
||||
return;
|
||||
}
|
||||
data.name = this.name
|
||||
data.sex = this.sex;
|
||||
data.height = this.height;
|
||||
data.birthday = this.birthday;
|
||||
data.id = this.user.familyid
|
||||
console.log("提交", data)
|
||||
this.subInfo(data);
|
||||
},
|
||||
subInfo(data) {
|
||||
let that = this
|
||||
that.$model.getsubmit(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
that.$tools.msg("提交成功");
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
} else {
|
||||
that.$tools.msg(res.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
//确定年龄
|
||||
bindDateChange(e) {
|
||||
console.log(e.target.value, this.startDate)
|
||||
this.birthday = e.target.value
|
||||
},
|
||||
onAgeArr(e) {
|
||||
this.age = this.ageArr[e.target.value]
|
||||
},
|
||||
//确定性别
|
||||
onsexArr(e) {
|
||||
this.sex = this.sexItem[e.target.value] == "男" ? 1 : 2
|
||||
},
|
||||
onTap() {
|
||||
this.height = ""
|
||||
this.isHeight = false
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
var agedata = []
|
||||
for (var i = 12; i <= 80; i++) {
|
||||
agedata.push(i);
|
||||
}
|
||||
this.ageArr = agedata
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.box {
|
||||
height: 100vh;
|
||||
// padding: 0 15px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.touxiang {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
margin: 0 auto;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.headbox {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 70px;
|
||||
margin: 15px 0 30px;
|
||||
}
|
||||
|
||||
.headimage,
|
||||
.icontouxiang {
|
||||
display: block;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.icontouxiang {
|
||||
font-size: 70px;
|
||||
color: $btncolor;
|
||||
}
|
||||
|
||||
.lanBox {
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.lan {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
padding: 5px 0;
|
||||
margin: 5px 15px;
|
||||
border-bottom: 1px solid #f7f7f7;
|
||||
}
|
||||
|
||||
.lan .left {
|
||||
width: 24%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lan .right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 72%;
|
||||
min-height: 38px;
|
||||
box-sizing: border-box;
|
||||
line-height: 36px;
|
||||
position: relative;
|
||||
text-align: right;
|
||||
|
||||
picker {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
border: none;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
color: #333333;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: auto;
|
||||
margin: 40px 15px 0;
|
||||
}
|
||||
|
||||
.lan2 {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: #f7f7f7;
|
||||
font-size: 12px;
|
||||
padding-left: 15px;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
<template>
|
||||
<view class="box">
|
||||
<view class="lanBox">
|
||||
<form action>
|
||||
<view class="headbox">
|
||||
<view class="touxiang">
|
||||
<image v-if="memInfo.headimg" :src="memInfo.headimg" class="headimage" />
|
||||
<icon v-else class="t-icon t-icon-touxiang headimage"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">用户名</view>
|
||||
<view class="right">
|
||||
<input name="name" type="text" v-model="memInfo.name" placeholder="请输入用户名/昵称" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">性别</view>
|
||||
<view class="right">
|
||||
<picker mode="selector" :range="sexItem" @change="onsexArr">
|
||||
<view class="uni-input">{{!memInfo.sex?'请选择':memInfo.sex==1?'男':'女'}}</view>
|
||||
<icon class="iconfont icon-arrow-down"></icon>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">身高</view>
|
||||
<view class="right">
|
||||
<input type="digit" class="mr-5" v-model="memInfo.height" placeholder="请输入身高"/> cm
|
||||
</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">出生日期</view>
|
||||
<view class="right">
|
||||
<picker class="picker" mode="date" :end="startDate" :value="memInfo.birthday"
|
||||
@change="bindDateChange">
|
||||
<view class="uni-input">{{memInfo.birthday?memInfo.birthday:"请选择"}}</view>
|
||||
<icon class="iconfont icon-arrow-down"></icon>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
<view v-if="isHeight" class="slidePopup">
|
||||
<view class="bg" @click="onTap">
|
||||
<view class="slide-box" @click.stop>
|
||||
<view class="btnGroup">
|
||||
<view class="subtn close" @click="onTap">取消</view>
|
||||
<view class="heightVal">{{memInfo.height}}cm</view>
|
||||
<view class="subtn" @click="isHeight = false">确定</view>
|
||||
</view>
|
||||
<slide-choose v-model="memInfo.height" ref="slide"></slide-choose>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn" @click="confirmInfo">提交</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ageArr: [],
|
||||
sexItem: [
|
||||
"男",
|
||||
"女"
|
||||
],
|
||||
isHeight: false,
|
||||
isEdit: false,
|
||||
memInfo: {
|
||||
birthday: "",
|
||||
height: "",
|
||||
sex: "",
|
||||
name: ""
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
startDate() {
|
||||
return this.$tools.getDate('start');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 提交
|
||||
confirmInfo() {
|
||||
let that = this
|
||||
that.isHeight = false
|
||||
if (!this.memInfo.name) {
|
||||
this.$tools.msg("请输入用户名")
|
||||
return;
|
||||
}
|
||||
if (!this.memInfo.sex) {
|
||||
this.$tools.msg("请选择性别")
|
||||
return;
|
||||
}
|
||||
if (!this.memInfo.height) {
|
||||
this.$tools.msg("请选则身高")
|
||||
return;
|
||||
}
|
||||
if (!this.memInfo.birthday) {
|
||||
this.$tools.msg("请选择出生日期")
|
||||
return;
|
||||
}
|
||||
// console.log("提交", this.memInfo)
|
||||
that.subInfo(this.memInfo)
|
||||
},
|
||||
subInfo(data) {
|
||||
let that = this
|
||||
data.fansid = uni.getStorageSync("unionid");
|
||||
that.$model.getsubmit(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
if (that.isEdit) {
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.user.id
|
||||
})
|
||||
}
|
||||
that.$store.dispatch("getFamilyList")
|
||||
that.$tools.msg("提交成功");
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
} else {
|
||||
that.$tools.msg(res.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
//确定年龄
|
||||
bindDateChange(e) {
|
||||
// console.log("年龄", e)
|
||||
this.memInfo.birthday = e.target.value
|
||||
},
|
||||
//确定性别
|
||||
onsexArr(e) {
|
||||
// console.log("性别", e)
|
||||
this.memInfo.sex = this.sexItem[e.target.value] == "男" ? 1 : 2
|
||||
},
|
||||
// 确定身份
|
||||
ontypeArr(e) {
|
||||
this.type = this.typeItem[e.target.value] == "成人" ? 1 : this.typeItem[e.target.value] == "儿童" ? 2 : 3
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
var agedata = []
|
||||
for (var i = 12; i <= 80; i++) {
|
||||
agedata.push(i);
|
||||
}
|
||||
this.ageArr = agedata
|
||||
// 编辑
|
||||
if (options.familayData) {
|
||||
let info = options.familayData
|
||||
this.memInfo = JSON.parse(info)
|
||||
this.isEdit = true
|
||||
// console.log("编辑", this.memInfo)
|
||||
}
|
||||
// 添加
|
||||
if (options.type) {
|
||||
this.isEdit = false
|
||||
this.memInfo = {
|
||||
birthday: "",
|
||||
height: "",
|
||||
sex: "",
|
||||
name: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.box {
|
||||
height: 100vh;
|
||||
padding: 0 15px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.headimage,
|
||||
.icontouxiang {
|
||||
display: block;
|
||||
width: 65px;
|
||||
height: 65px;
|
||||
font-size: 65px;
|
||||
color: $btncolor;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.headbox {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 65px;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
.lanBox {
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.lan {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
padding: 5px 0;
|
||||
margin: 4px auto;
|
||||
border-bottom: 1px solid #f7f7f7;
|
||||
|
||||
input {
|
||||
border: none;
|
||||
background: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.lan .left {
|
||||
width: 24%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lan .right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 72%;
|
||||
min-height: 38px;
|
||||
box-sizing: border-box;
|
||||
line-height: 36px;
|
||||
position: relative;
|
||||
text-align: right;
|
||||
|
||||
picker {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
border: none;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
color: #333333;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin: 10px auto 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
<template>
|
||||
<view class="common">
|
||||
<view class="header" v-if="info">
|
||||
<view class="left">
|
||||
<image :src="info.headimg" class="image1" />
|
||||
<view class="left_sm">
|
||||
<view class="name">
|
||||
<view>{{info.name?info.name:""}}</view>
|
||||
<view class="right">
|
||||
<view v-if="info.isself != 1" @click="deldet(Infoid)" class="guanliyuan">删除</view>
|
||||
<view @click="editorInfo()" class="guanliyuan">编辑</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-5">
|
||||
<text>{{info.sex==0?'未知':info.sex==2?'女':'男'}}</text>
|
||||
<text>{{info.height}}cm</text>
|
||||
<text>{{info.mage?info.mage:"0岁"}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y class="list ">
|
||||
<view class="history" v-if="ranklist.length">
|
||||
<view class="list-item" v-for="(item ,index) in ranklist" :key="index">
|
||||
<view class="item">
|
||||
<view class="time">
|
||||
<icon class="t-icon t-icon-shijian-mianxing-0"></icon>
|
||||
<text>{{item.createtime}}</text>
|
||||
</view>
|
||||
<view>{{item.height}}<text>身高</text></view>
|
||||
<view>{{item.weight}}<text>体重</text></view>
|
||||
<view>{{item.bmi}}<text>BMI</text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="endtext" v-if="!lastPage || page >= lastPage">—— 到底了,看看别的吧 ——</view>
|
||||
</view>
|
||||
<view class="nolist" v-else>
|
||||
<icon class="iconfont icon-zanwu"></icon>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ranklist: [],
|
||||
info: {},
|
||||
memberText: null,
|
||||
memberType: [],
|
||||
page: 1,
|
||||
lastPage: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"])
|
||||
},
|
||||
onLoad(option) {
|
||||
this.page = 1
|
||||
this.ranklist = []
|
||||
console.log("id", option)
|
||||
if (option.id) {
|
||||
this.Infoid = option.id
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.ranklist = []
|
||||
this.gethistory(this.Infoid)
|
||||
this.getHistoryList(this.Infoid)
|
||||
},
|
||||
onReachBottom() {
|
||||
console.log(this.lastPage, this.page)
|
||||
if (!this.lastPage || this.page >= this.lastPage) {
|
||||
uni.showToast({
|
||||
title: '没有更多数据!',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.page++
|
||||
this.getHistoryList(this.Infoid)
|
||||
},
|
||||
methods: {
|
||||
// 历史记录
|
||||
getHistoryList(id) {
|
||||
this.$model.getHistoryList({
|
||||
familyId: id,
|
||||
pageNo: this.page,
|
||||
pageSize: 10,
|
||||
}).then((res) => {
|
||||
if (res.code != 0) {
|
||||
return
|
||||
}
|
||||
this.ranklist = this.ranklist.concat(res.data.rows)
|
||||
this.lastPage = res.data.totalpage
|
||||
})
|
||||
},
|
||||
// 信息
|
||||
gethistory(id) {
|
||||
this.$model.getdetail({
|
||||
id: id
|
||||
}).then((res) => {
|
||||
if (res.code != 0) {
|
||||
return
|
||||
}
|
||||
this.info = res.data
|
||||
})
|
||||
},
|
||||
// 编辑
|
||||
editorInfo() {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/me/adduser?familayData=" + JSON.stringify(this.info),
|
||||
})
|
||||
},
|
||||
//删除
|
||||
deldet(id) {
|
||||
let that = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '确定删除该成员吗',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
that.$model.getdelete({
|
||||
id: id,
|
||||
}).then(res => {
|
||||
if (res.code != 0) return
|
||||
that.$tools.msg("删除成功!");
|
||||
that.getFamilyList()
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
that.$tools.msg("您已取消删除!");
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getFamilyList() {
|
||||
let that = this
|
||||
that.$model.getFamilyList({}).then(res => {
|
||||
that.$store.commit("changeFamilay", res)
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: res[0].familyid
|
||||
})
|
||||
uni.switchTab({
|
||||
url: '/pages/me/me'
|
||||
});
|
||||
}).catch(e => {})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.list {
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
text-align: center;
|
||||
margin: 10px 0 15px;
|
||||
}
|
||||
|
||||
.item {
|
||||
background-color: #fff;
|
||||
padding: 5px 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-radius: 10px;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
margin-bottom: 30rpx;
|
||||
line-height: 40rpx;
|
||||
|
||||
text {
|
||||
width: 100%;
|
||||
font-size: 24rpx;
|
||||
display: block;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
view {
|
||||
width: 18%;
|
||||
}
|
||||
|
||||
.time {
|
||||
width: 32% !important;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
text {
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
margin-top: 3px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
.common {
|
||||
padding: 0 15px;
|
||||
min-height: calc(100vh - 90px);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 90px;
|
||||
background: $mainColor;
|
||||
position: fixed;
|
||||
top: 0rem;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
z-index: 99;
|
||||
padding: 0 10px;
|
||||
justify-content: space-between;
|
||||
|
||||
.left {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.left_sm {
|
||||
text-align: left;
|
||||
color: #FFFFFF;
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
top: 25px;
|
||||
right: 0;
|
||||
|
||||
.name {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
padding-right: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.type,
|
||||
.type2 {
|
||||
background: #fff;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
padding: 0 3px !important;
|
||||
font-size: 12px !important;
|
||||
border-radius: 10px;
|
||||
line-height: initial;
|
||||
color: $btncolor;
|
||||
}
|
||||
|
||||
.image1 {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
float: left;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: left;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
text-align: right;
|
||||
font-size: 14px;
|
||||
|
||||
.guanliyuan {
|
||||
border: 1px solid #fff;
|
||||
padding: 2px 6px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leftChild {
|
||||
width: 100% !important;
|
||||
padding: 10px 0 !important;
|
||||
|
||||
view {
|
||||
min-width: auto !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class="formbox">
|
||||
<view class="input">
|
||||
<view class="t-icon t-icon-dianhuatianchong"></view>
|
||||
<input type="text" v-model="formdata.phone" placeholder="在此输入您的联系方式" />
|
||||
</view>
|
||||
<view class="input textarea">
|
||||
<view class="t-icon t-icon-xinxi"></view>
|
||||
<textarea v-model="formdata.content" name="content" placeholder-style="font-size:13px;margin-top:10px;"
|
||||
placeholder="有什么想说的,尽管来吧..." />
|
||||
</view>
|
||||
<view class="btn " type="button" @click="submit">提交</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
formdata: {
|
||||
phone: "",
|
||||
content: ""
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
if (!this.formdata.phone.trim()) {
|
||||
this.$tools.msg("请输入联系方式");
|
||||
return
|
||||
}
|
||||
if (!/(^1[3|4|5|7|8][0-9]{9}$)/.test(this.formdata.phone)) {
|
||||
this.$tools.msg('请输入正确的联系方式');
|
||||
return;
|
||||
}
|
||||
if (!this.formdata.content.trim()) {
|
||||
this.$tools.msg("请输入建议");
|
||||
return
|
||||
}
|
||||
this.$model.submitadvice(this.formdata).then((res) => {
|
||||
this.$tools.msg(res.message)
|
||||
setTimeout(function() {
|
||||
uni.switchTab({
|
||||
url: "/pages/me/me"
|
||||
})
|
||||
}, 500)
|
||||
|
||||
}).catch((res) => {
|
||||
this.$tools.msg('提交失败,请稍后重试!')
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.formbox {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.input {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid #f7f7f7;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 1.5rem;
|
||||
line-height: 1.5rem;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/deep/textarea {
|
||||
width: 100%;
|
||||
height: 6.5rem;
|
||||
line-height: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
margin: 30px auto;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
<template>
|
||||
<view class="common">
|
||||
<view class="history" v-if="ranklist.length">
|
||||
<delectList :list="ranklist" :type="user.type" :border="false" @changeDelete="changeDelete"></delectList>
|
||||
<view class="endtext" v-if="!lastPage || page >= lastPage">—— 到底了,看看别的吧 ——</view>
|
||||
</view>
|
||||
<view class="nolist" v-if="!lastPage">
|
||||
<icon class="iconfont icon-zanwu"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import delectList from "@/components/mark-slide-list/mark-slide-list.vue"
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
components: {
|
||||
delectList
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
buttonList: [{
|
||||
title: '删除',
|
||||
background: '#ff3b32'
|
||||
}],
|
||||
list: [
|
||||
"测量时间",
|
||||
"体重",
|
||||
"BMI",
|
||||
"操作",
|
||||
],
|
||||
ranklist: [],
|
||||
page: 1,
|
||||
lastPage: 1,
|
||||
type: null,
|
||||
id: null,
|
||||
startX: 0,
|
||||
endX: 0
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
let that = this
|
||||
that.getList(1)
|
||||
},
|
||||
onReachBottom() {
|
||||
let that = this
|
||||
console.log("this.lastPage", this.lastPage)
|
||||
if (!this.lastPage || this.page >= this.lastPage) {
|
||||
uni.showToast({
|
||||
title: '没有更多数据!',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.page++
|
||||
this.getList(this.page)
|
||||
},
|
||||
methods: {
|
||||
changeDelete(item) {
|
||||
let that = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '是否删除当前测量记录?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
that.$model.gethistorydelete({
|
||||
id: item.id,
|
||||
}).then((res) => {
|
||||
if (res.code != 0) {
|
||||
that.$tools.msg(res.message)
|
||||
return
|
||||
}
|
||||
that.ranklist.splice(that.ranklist.findIndex(ite => ite.id === item
|
||||
.id), 1)
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: that.user.familyid,
|
||||
})
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: that.user.birthday,
|
||||
familyid: that.user.familyid,
|
||||
height: that.user.height,
|
||||
sex: that.user.sex,
|
||||
})
|
||||
|
||||
that.$tools.msg("删除成功")
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
that.$tools.msg("您已取消操作!");
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
getList(page) {
|
||||
let that = this
|
||||
that.$model.getHistoryList({
|
||||
familyId: that.user.familyid,
|
||||
pageNo: page,
|
||||
pageSize: 10
|
||||
}).then((res) => {
|
||||
console.log("历史记录", res)
|
||||
if (res.code != 0) return
|
||||
res.data.rows.forEach(item => {
|
||||
item.slide_x = 0
|
||||
})
|
||||
this.ranklist = this.ranklist.concat(res.data.rows)
|
||||
this.lastPage = res.data.totalpage
|
||||
})
|
||||
},
|
||||
// 滑动开始
|
||||
touchStart(e) {
|
||||
// 记录初始位置
|
||||
this.startX = e.touches[0].clientX
|
||||
},
|
||||
// 滑动结束
|
||||
touchEnd(e) {
|
||||
console.log("2", e)
|
||||
// 当前滑动的父级元素
|
||||
let parentElement = e.currentTarget
|
||||
// 记录结束位置
|
||||
this.endX = e.changedTouches[0].clientX
|
||||
// 左滑
|
||||
if (parentElement.dataset.type == 0 && this.startX - this.endX > 30) {
|
||||
this.restSlide()
|
||||
parentElement.dataset.type = 1
|
||||
}
|
||||
// 右滑
|
||||
if (parentElement.dataset.type == 1 && this.startX - this.endX < -30) {
|
||||
this.restSlide()
|
||||
parentElement.dataset.type = 0
|
||||
}
|
||||
this.startX = 0
|
||||
this.endX = 0
|
||||
},
|
||||
// 判断当前是否有滑块处于滑动状态
|
||||
checkSlide() {
|
||||
let listItems = document.querySelectorAll('.list')
|
||||
for (let i = 0; i < listItems.length; i++) {
|
||||
if (listItems[i].dataset.type == 1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
// 复位滑动状态
|
||||
restSlide() {
|
||||
let listItems = document.querySelectorAll('list')
|
||||
// 复位
|
||||
for (let i = 0; i < listItems.length; i++) {
|
||||
listItems[i].dataset.type = 0
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped="scoped" lang="scss">
|
||||
.common {
|
||||
min-height: calc(100vh - 40px);
|
||||
padding-bottom: 15px
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="box">
|
||||
<view class="form lanBox">
|
||||
<view class="lan border-bottom" v-for="(item,index) in list" :key="index">
|
||||
<view class="left">
|
||||
<view class="icon">
|
||||
<icon class="t-icon" :class="'t-icon-'+item.key"></icon>
|
||||
</view>
|
||||
{{item.title}}
|
||||
</view>
|
||||
<view class="center">
|
||||
<view v-if="item.title!='肥胖等级'">
|
||||
<text>{{item.fvalue?item.fvalue:"0"}}</text><text v-if="item.dw">{{item.dw}}</text>
|
||||
</view>
|
||||
<view v-if="item.title=='肥胖等级'"><text>{{item.fevaluation}}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/weight.png"></image>体重
|
||||
</view>
|
||||
<view class="right">{{memInfo.weight?memInfo.weight:"-"}}kg</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/height.png"></image>身高
|
||||
</view>
|
||||
<view class="right">{{memInfo.height?memInfo.height:"-"}}cm</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/bmi.png"></image>BMI
|
||||
</view>
|
||||
<view class="right">{{memInfo.bmi?memInfo.bmi:"-"}}</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/fat_r.png"></image>体脂率
|
||||
</view>
|
||||
<view class="right">{{memInfo.fat_r?memInfo.fat_r:"-"}}%</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/fat_w.png"></image>脂肪量
|
||||
</view>
|
||||
<view class="right">{{memInfo.fat_w?memInfo.fat_w:"-"}}%</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/muscle.png"></image>肌肉率
|
||||
</view>
|
||||
<view class="right">{{memInfo.muscle?memInfo.muscle:"-"}}%</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/water.png"></image>水分
|
||||
</view>
|
||||
<view class="right">{{memInfo.water?memInfo.water:"-"}}</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/bone.png"></image>骨重
|
||||
</view>
|
||||
<view class="right">{{memInfo.bone?memInfo.bone:"-"}}kg</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/visceral.png"></image>内脏指数
|
||||
</view>
|
||||
<view class="right">{{memInfo.visceral?memInfo.visceral:"-"}}</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/sfr.png"></image>皮下脂肪
|
||||
</view>
|
||||
<view class="right">{{memInfo.sfr?memInfo.sfr:"-"}}%</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/protein.png"></image>蛋白率
|
||||
</view>
|
||||
<view class="right">{{memInfo.protein?memInfo.protein:"-"}}%</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/bodyage.png"></image>身体年龄
|
||||
</view>
|
||||
<view class="right">{{memInfo.bodyage?memInfo.bodyage:"-"}}</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/kcal.png"></image>基础代谢率
|
||||
</view>
|
||||
<view class="right">{{memInfo.kcal?memInfo.kcal:'0'}}kcal</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/muscleval.png"></image>肌肉量
|
||||
</view>
|
||||
<view class="right">{{memInfo.muscleval?memInfo.muscleval:"-"}}kg</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/lbm.png"></image>去脂体重
|
||||
</view>
|
||||
<view class="right">{{memInfo.lbm?memInfo.lbm:"-"}}kg</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/proteinval.png"></image>蛋白量
|
||||
</view>
|
||||
<view class="right">{{memInfo.proteinval?memInfo.proteinval:'0'}}kg</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/fat.png"></image>肥胖等级
|
||||
</view>
|
||||
<view class="right">{{memInfo.fatlevel?memInfo.fatlevel:'0'}}</view>
|
||||
</view>
|
||||
<view class="lan border-bottom">
|
||||
<view class="left">
|
||||
<image src="@/static/body.png"></image>体型
|
||||
</view>
|
||||
<view class="right">{{memInfo.body?memInfo.body:'0'}}</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: {},
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
let info = options.index
|
||||
let memInfo = JSON.parse(info)
|
||||
this.list = this.weightInfo.infoList(memInfo)
|
||||
console.log(this.list)
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.box {
|
||||
min-height: 100vh;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.lanBox {
|
||||
padding: 0px 15px 0;
|
||||
}
|
||||
|
||||
.lan {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #f7f7f7;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
padding-left: 30px;
|
||||
|
||||
.icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
padding: 3px;
|
||||
background-color: #aaa;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 50%;
|
||||
min-height: 38px;
|
||||
box-sizing: border-box;
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<template>
|
||||
<view class="common">
|
||||
<view class="add" @click="addInfo('add')">
|
||||
<icon class="iconfont icon-tianjia"></icon>添加成员
|
||||
</view>
|
||||
<view class="box" v-if="familayList.lenght!=0">
|
||||
<view class="list" v-for="(item ,index) in familayList" :key="index" @click="datail(item.id)">
|
||||
<image :src="item.headimg" class="image1" />
|
||||
<view class="left">
|
||||
<view class="title">{{item.name?item.name:""}}</view>
|
||||
<view class="title2">
|
||||
<text>{{item.sex==0?'未知':item.sex==1?'男':'女'}}</text>
|
||||
<text>{{item.mage?item.mage:'0岁'}}</text>
|
||||
<text>{{item.type}}</text>
|
||||
</view>
|
||||
<view class="title2">最后测量时间:{{item.lasthearttime||'-'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
没有数据了!
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
ranklist: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["familayList", "user"])
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
//添加
|
||||
addInfo(type) {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/me/adduser?type=${type}"
|
||||
})
|
||||
},
|
||||
//查看
|
||||
datail(id) {
|
||||
uni.navigateTo({
|
||||
url: `/pageTwo/me/detail?id=` + id,
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.common {
|
||||
padding: 15px;
|
||||
height: calc(100vh - 30px);
|
||||
}
|
||||
|
||||
.add {
|
||||
width: 135px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
color: #fff;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: $btncolor;
|
||||
}
|
||||
|
||||
.list {
|
||||
width: auto;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 15px;
|
||||
flex-wrap: wrap;
|
||||
padding: 10px 15px;
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
|
||||
.image1 {
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 70%;
|
||||
|
||||
.title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.title2 {
|
||||
margin-top: 5px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
|
||||
text {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class="bgheight" v-if="!isShowA">
|
||||
<view v-if="listA">
|
||||
<view class="btn" @tap="handleListx(1)">重新测评</view>
|
||||
<view class="box">
|
||||
<view class="name">
|
||||
<view>本次体质评估结果为</view>
|
||||
</view>
|
||||
<view class="conbt">
|
||||
{{listA.bodytype}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="box" v-if="listA.list.length">
|
||||
<view class="h2">体质解读:</view>
|
||||
<view v-for="(item,index) in listA.list" :key="index">
|
||||
<view class="title">{{item.bodytype}}</view>
|
||||
<view class="con">
|
||||
<view class="text" v-show="item.feature"><text>特征:</text>{{item.feature}}</view>
|
||||
<view class="text" v-show="item.people"><text>重点人群:</text>{{item.people}}</view>
|
||||
<view class="text" v-show="item.sick"><text>患病倾向:</text>{{item.sick}}</view>
|
||||
<view class="text" v-show="item.health"><text>调养方式:</text>{{item.health}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips" v-if="listA.referlist">
|
||||
{{listA.referlist}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 评估 -->
|
||||
<view class="commonAll" v-else>
|
||||
<view class="h2">请根据近一年的体验和感觉,回答以下问题</view>
|
||||
<view class="box" v-for="(item,index) in infoListA.slice((currpage-1)*eachpage,currpage*eachpage)"
|
||||
:key="index">
|
||||
<view v-for="(ite, ind) in item.qalist" :key="ind">
|
||||
<view class="h5">{{ite.title}}</view>
|
||||
<view class="item">
|
||||
<view class="group" v-for="(it, id) in ite.data" :key="id" @click="Changeradio(it)">
|
||||
<icon class="iconfont radioimg"
|
||||
:class="[dasC.indexOf(it.val)!=-1?'icon-radio':'icon-kongradio']">
|
||||
</icon>
|
||||
<view>{{it.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="page" v-if='!listA'>
|
||||
<view class="pre" v-if="currpage>1" @click="pre">上一页</view>
|
||||
<view v-if="currpage<pagesum" @click="next">下一页</view>
|
||||
<view class="btn" v-if="currpage==pagesum" @click="handlesub">
|
||||
提交
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
info() {
|
||||
return this.user
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
let that = this
|
||||
that.handleTypeInfo()
|
||||
},
|
||||
methods: {
|
||||
//测评结果
|
||||
handleTypeInfo() {
|
||||
let that = this
|
||||
that.$model.getbodyinfo({
|
||||
familyid: that.user.familyid,
|
||||
}).then(res => {
|
||||
if (res.code != 0) {
|
||||
that.handleListx(1)
|
||||
return
|
||||
}
|
||||
that.listA = res.data
|
||||
that.isShowA = false
|
||||
console.log("计算成功,去查看结果吧!")
|
||||
})
|
||||
|
||||
},
|
||||
// 重新测评
|
||||
handleListx(ind) {
|
||||
let that = this
|
||||
that.isShowA = true
|
||||
that.currpage = 1
|
||||
that.dasA = []
|
||||
that.dasC = []
|
||||
that.listA = ""
|
||||
that.tmidlistA = []
|
||||
that.infoListA = []
|
||||
that.$model.getbodylist({
|
||||
isrestart: ind,
|
||||
familyid: that.user.familyid,
|
||||
}).then(res => {
|
||||
console.log(123, res)
|
||||
if (res.code != 0) return
|
||||
that.pagesum = Math.ceil(res.data.length / that.eachpage);
|
||||
that.infoListA = res.data
|
||||
})
|
||||
|
||||
},
|
||||
// 测评选择
|
||||
Changeradio(tmitem) {
|
||||
let that = this
|
||||
if (that.tmidlistA.indexOf(tmitem.id) == -1) {
|
||||
console.log(0)
|
||||
that.tmidlistA.push(tmitem.id)
|
||||
that.dasC.push(tmitem.val);
|
||||
that.dasA.push(tmitem)
|
||||
} else {
|
||||
for (var n = 0; n < that.tmidlistA.length; n++) {
|
||||
if (tmitem.id == that.tmidlistA[n]) {
|
||||
console.log(1)
|
||||
if (that.dasC.indexOf(tmitem.val) == -1) {
|
||||
that.tmidlistA.push(tmitem.id)
|
||||
that.dasC.push(tmitem.val);
|
||||
that.dasA.push(tmitem)
|
||||
console.log(2)
|
||||
}
|
||||
that.tmidlistA.splice(n, 1)
|
||||
that.dasC.splice(n, 1);
|
||||
that.dasA.splice(n, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 提交
|
||||
handlesub() {
|
||||
let that = this
|
||||
var obj = {}
|
||||
let newArr = []
|
||||
that.dasA.forEach(function(item, suffix) {
|
||||
if (!obj[item.valId]) {
|
||||
var arr = {
|
||||
id: '',
|
||||
list: []
|
||||
};
|
||||
arr.id = item.valId
|
||||
arr.list.push({
|
||||
id: item.id,
|
||||
score: item.value
|
||||
})
|
||||
newArr.push(arr);
|
||||
obj[item.valId] = item;
|
||||
} else {
|
||||
for (var q = 0; q < newArr.length; q++) {
|
||||
if (newArr[q].id == item.valId) {
|
||||
newArr[q].list.push({
|
||||
id: item.id,
|
||||
score: item.value
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
// for (var i = 0; i < that.infoListA.length; i++) {
|
||||
// var arr = {
|
||||
// id: '',
|
||||
// list: []
|
||||
// };
|
||||
// arr.id = that.infoListA[i].id
|
||||
// for (var e = 0; e < that.infoListA[i].qalist.length; e++) {
|
||||
// arr.list.push({
|
||||
// id: that.infoListA[i].qalist[e].Id,
|
||||
// score: 3
|
||||
// })
|
||||
// }
|
||||
// newArr.push(arr)
|
||||
// }
|
||||
console.log("去计算", newArr)
|
||||
// if (newArr.length < 7 || newArr.length < 9) {
|
||||
// that.$api.msg("请先完成问答")
|
||||
// return
|
||||
// }
|
||||
that.$model.getbodyresultinfo({
|
||||
appid: uni.getStorageSync("appid"),
|
||||
familyid: that.user.familyid,
|
||||
data: newArr
|
||||
})
|
||||
.then(res => {
|
||||
console.log('res', res)
|
||||
that.tmidlistA = []
|
||||
that.dasA = []
|
||||
that.dasC = []
|
||||
if (res.code != 0) {
|
||||
that.$tools.msg(res.message)
|
||||
return
|
||||
}
|
||||
that.listA = res.data
|
||||
that.isShowA = false
|
||||
that.currpage = 1
|
||||
console.log("计算成功,去查看结果吧!")
|
||||
})
|
||||
},
|
||||
pre() {
|
||||
this.currpage--
|
||||
},
|
||||
next() {
|
||||
let that = this
|
||||
that.currpage++
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShowA: true,
|
||||
dasA: [],
|
||||
dasC: [],
|
||||
listA: [],
|
||||
infoListA: [],
|
||||
tmidlistA: [],
|
||||
pagesum: null, //总页数
|
||||
currpage: 1, //当前页数
|
||||
eachpage: 2, //每页行数
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
background-color: #fff;
|
||||
padding: 15px;
|
||||
min-height: calc(100vh - 30px);
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.h5 {
|
||||
margin: 15px 0 10px;
|
||||
|
||||
}
|
||||
|
||||
.bgheight {
|
||||
.name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #f19601;
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.conbt {
|
||||
font-size: 14px;
|
||||
line-height: 25px;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.box .conbt:nth-last-child(1) text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
margin: 15px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.con {
|
||||
line-height: 25px;
|
||||
|
||||
text {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border: none;
|
||||
background: #f19601;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
width: 100px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
float: right;
|
||||
// margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.uni-list-cell {
|
||||
display: flex;
|
||||
width: 60%;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
:nth-child(even).uni-list-cell {
|
||||
width: 30%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.commonAll {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
text-align: center;
|
||||
margin: 20px auto;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
view {
|
||||
width: 150px;
|
||||
background: #dfdfdf;
|
||||
padding: 5px 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: #f19601;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
width: 50%;
|
||||
justify-content: end;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
font-size: 20px;
|
||||
color: #dfdfdf;
|
||||
display: flex;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.icon-radio {
|
||||
color: #f19601;
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 10px;
|
||||
line-height: 22px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/target/target",
|
||||
"style": {
|
||||
"navigationBarTitleText": "目标"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/compk/compk",
|
||||
"style": {
|
||||
"navigationBarTitleText": "对比"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "pages/me/me",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/active",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设备激活",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path": "pages/search/devType",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设备搜索"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": [{
|
||||
"root": "pageTwo",
|
||||
"pages": [{
|
||||
"path": "login/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "login/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "协议"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "login/userinfo",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path": "home/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "报告页"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "compk/pkdetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "对比详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "me/history",
|
||||
"style": {
|
||||
"navigationBarTitleText": "历史记录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "me/feedBack",
|
||||
"style": {
|
||||
"navigationBarTitleText": "意见反馈"
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path": "me/manage",
|
||||
"style": {
|
||||
"navigationBarTitleText": "用户管理"
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path": "me/adduser",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
|
||||
}, {
|
||||
"path": "me/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path": "me/info",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path": "survey/survey",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
]
|
||||
}, {
|
||||
"root": "BLEPages",
|
||||
"pages": [{
|
||||
"path": "adult/H01pro",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "adult/PCD01pro",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "adult/PCL01",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "adult/H09B",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
}
|
||||
|
||||
, {
|
||||
"path": "adult/F01B",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
}],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "#fff",
|
||||
"navigationBarBackgroundColor": "#00c6c6",
|
||||
"backgroundColor": "#fff"
|
||||
},
|
||||
// 切换导航
|
||||
"tabBar": {
|
||||
"color": "#333",
|
||||
"selectedColor": "#00c6c6",
|
||||
"backgroundColor": "#fff",
|
||||
"list": [{
|
||||
"pagePath": "pages/index/index",
|
||||
"iconPath": "static/tab_sy.png",
|
||||
"selectedIconPath": "static/tab_sy01.png",
|
||||
"text": "首页"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/target/target",
|
||||
"iconPath": "static/tab_sj.png",
|
||||
"selectedIconPath": "static/tab_sj01.png",
|
||||
"text": "目标"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/compk/compk",
|
||||
"iconPath": "static/tab_db.png",
|
||||
"selectedIconPath": "static/tab_db01.png",
|
||||
"text": "对比"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/me/me",
|
||||
"iconPath": "static/tab_me.png",
|
||||
"selectedIconPath": "static/tab_me01.png",
|
||||
"text": "我的"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class=" calendar">
|
||||
<!-- 日历 -->
|
||||
<ren-calendar ref='ren' :markDays='markDays' @onDayClick='onDayClick' @onMonthClickPre='onMonthClickPre'
|
||||
@onMonthClickNext="onMonthClickNext" v-if="isShow">
|
||||
</ren-calendar>
|
||||
<!-- -->
|
||||
<view class="box" v-if="infoList.length">
|
||||
<view class="list" v-for="(item,index) in infoList" :key="index" @click="addMemberTags(item.id,item)">
|
||||
<!-- 成人 -->
|
||||
<view class="item">
|
||||
<view class="check">
|
||||
<icon class="iconfont" :class="isActive.indexOf(item.id)!=-1?'icon-radio':'icon-kongradio'">
|
||||
</icon>
|
||||
</view>
|
||||
<view>{{item.height}}<text>身高</text></view>
|
||||
<view>{{item.weight}}<text>体重</text></view>
|
||||
<view>{{item.bmi}}<text>BMI</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="bottom">
|
||||
<view class="list" v-for="(ite,ind) in ActiveDays" :key="ind" v-if="isActive"
|
||||
@click="addMemberTags(ite.id,ite)">
|
||||
<view class="item borderRadius">
|
||||
<view class="time">{{ite.createtime}}</view>
|
||||
<view>{{ite.height}}<text>身高</text></view>
|
||||
<view>{{ite.weight}}<text>体重</text></view>
|
||||
<view>{{ite.bmi}}<text>BMI</text></view>
|
||||
<view class="check">
|
||||
<icon class="iconfont icon-quxiao"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pkclass" v-if="length==2">vs</view>
|
||||
<view :class="{'active':length!=2}" class="btn" @click="handlePK">减脂对比</view>
|
||||
</view>
|
||||
</view>
|
||||
<userPopup></userPopup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import userPopup from '@/components/userLogin.vue'
|
||||
import RenCalendar from '@/components/ren-calendar/ren-calendar.vue';
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
components: {
|
||||
userPopup,
|
||||
RenCalendar,
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "TrendPk"]),
|
||||
length() {
|
||||
return this.isActive.length
|
||||
},
|
||||
endDate() {
|
||||
return this.$tools.getDate("start")
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.token = uni.getStorageSync("token")
|
||||
},
|
||||
onShow() {
|
||||
let that = this
|
||||
that.startM = that.$tools.getDate("m").substring(0, 10)
|
||||
that.endM = that.$tools.getDate("m").substring(11, 21)
|
||||
that.infoList = []
|
||||
that.markDays = []
|
||||
that.list = []
|
||||
that.isActive = []
|
||||
that.ActiveDays = []
|
||||
that.isShow = false
|
||||
this.$nextTick(() => {
|
||||
that.isShow = true
|
||||
that.getList(that.startM, that.endM)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getList(start, end) {
|
||||
let that = this
|
||||
that.$model.GetTrendList({
|
||||
familyid: uni.getStorageSync('familyid'),
|
||||
starttime: start,
|
||||
endtime: end,
|
||||
}).then(res => {
|
||||
if (res) {
|
||||
that.markDays = res.pkList.Dlist
|
||||
that.list = res.pkList.list
|
||||
for (var i = 0; i < res.pkList.list.length; i++) {
|
||||
if (Date.parse(that.endDate) == Date.parse(res.pkList.list[i].createtime)) {
|
||||
that.infoList.push(res.pkList.list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
onMonthClickPre(data) {
|
||||
console.log("onMonthClickPre", data)
|
||||
let that = this
|
||||
let start = data.substring(0, 10)
|
||||
let end = data.substring(11, 21)
|
||||
that.infoList = []
|
||||
that.markDays = []
|
||||
that.list = []
|
||||
that.getList(start, end)
|
||||
},
|
||||
onDayClick(data) {
|
||||
let that = this
|
||||
this.infoList = []
|
||||
for (var i = 0; i < that.list.length; i++) {
|
||||
if (Date.parse(data.date) == Date.parse(that.list[i].createtime)) { //includes 检测数组是否有某个值
|
||||
this.infoList.push(that.list[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
addMemberTags(index, item) {
|
||||
var that = this;
|
||||
console.log("addMemberTags", index, item)
|
||||
// if (this.user.type != 1) return
|
||||
if (that.isActive.indexOf(index) == -1) {
|
||||
that.isActive.push(index);
|
||||
that.ActiveDays.push(item);
|
||||
} else {
|
||||
that.isActive.splice(that.isActive.indexOf(index), 1);
|
||||
that.ActiveDays.splice(that.ActiveDays.indexOf(item), 1);
|
||||
}
|
||||
if (that.isActive.length > 2) {
|
||||
that.isActive.splice(0, 1)
|
||||
that.ActiveDays.splice(0, 1);
|
||||
}
|
||||
},
|
||||
handlePK() {
|
||||
let that = this
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
if (that.isActive.length != 2) {
|
||||
that.$tools.msg("请先选择数据!")
|
||||
return
|
||||
}
|
||||
let info = {}
|
||||
info.familyid = uni.getStorageSync('familyid')
|
||||
info.firstId = that.isActive[0]
|
||||
info.secondId = that.isActive[1]
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/compk/pkdetail?info=" + JSON.stringify(info)
|
||||
})
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
markDays: [],
|
||||
infoList: [],
|
||||
list: [],
|
||||
isActive: [],
|
||||
ActiveDays: [],
|
||||
token: null,
|
||||
startM: null,
|
||||
endM: null,
|
||||
isShow: true,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
|
@ -0,0 +1,379 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class="tips">请在设备开机状态下,搜索设备</view>
|
||||
<view class="item" @click="handleWeight">开始搜索设备</view>
|
||||
<view class="devices_summary">已发现 {{devices.length}} 个设备:</view>
|
||||
<view>
|
||||
<scroll-view class="device_list" scroll-y scroll-with-animation v-if="popup">
|
||||
<view v-for="(item,index) in devices" :key="index" @tap="createBLEConnection(item)" class="device_item">
|
||||
<view>
|
||||
<text>{{item.name|| item.localName}}</text>
|
||||
</view>
|
||||
<view>mac地址:{{item.macAddr || item.deviceId}}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="tishi">
|
||||
<view class="text">
|
||||
<icon class="t-icon t-icon-tishi"></icon> 设备激活流程说明
|
||||
</view>
|
||||
<view class="dv">
|
||||
<text>1、打开手机蓝牙和位置信息</text>
|
||||
<text>2、ios系统需打开设置—>应用—>微信里的蓝牙权限</text>
|
||||
<text>3、设备亮屏状态下搜索蓝牙</text>
|
||||
<text>4、选择蓝牙进行激活</text>
|
||||
</view>
|
||||
</view>
|
||||
<userLogin :url="'active'"></userLogin>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var myTime;
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
import userLogin from "@/components/userLogin.vue"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
token: "",
|
||||
macAddr: "",
|
||||
code: "",
|
||||
deviceId: "",
|
||||
popup: false,
|
||||
devices: [],
|
||||
}
|
||||
},
|
||||
components: {
|
||||
userLogin
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isBluetoothTyle"])
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this
|
||||
console.log("设备code码", options)
|
||||
if (options) {
|
||||
that.code = options.code
|
||||
}
|
||||
that.token = uni.getStorageSync('token')
|
||||
that.login()
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
login() {
|
||||
let that = this
|
||||
uni.login({
|
||||
success(res) {
|
||||
if (res.code) {
|
||||
if (res.errMsg = "login:ok") {
|
||||
that.$model.onlogin({
|
||||
code: res.code,
|
||||
}).then(res => {
|
||||
if (res.code == 2) {
|
||||
uni.clearStorageSync()
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('changeUser')
|
||||
uni.setStorageSync('tenantid', res.data.tenantid)
|
||||
uni.setStorageSync('sessionid', res.data.sessionid)
|
||||
uni.setStorageSync('iswxphone', res.data.iswxphone)
|
||||
that.$store.commit("changeUserLogin", true)
|
||||
return
|
||||
} else {
|
||||
uni.setStorageSync('sessionid', res.data.sessionid)
|
||||
uni.setStorageSync('token', res.data.token)
|
||||
uni.setStorageSync('iswxphone', res.data.iswxphone)
|
||||
uni.setStorageSync('tenantid', res.data.tenantid)
|
||||
uni.setStorageSync('refreshtoken', res.data.refreshtoken)
|
||||
}
|
||||
}).catch(e => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
handleWeight() {
|
||||
let that = this
|
||||
that.devices = []
|
||||
if (!that.token) {
|
||||
that.$store.commit("changeUserLogin", true)
|
||||
return
|
||||
}
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.$store.commit("changeBluetooth", true);
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
},
|
||||
fail: e => {
|
||||
wx.hideLoading()
|
||||
console.log("openBluetoothAdapter失败", e)
|
||||
return that.$tools.getBluetoothAdapter(e)
|
||||
}
|
||||
});
|
||||
},
|
||||
startBluetoothDeviceDiscovery() {
|
||||
let that = this;
|
||||
wx.showLoading({
|
||||
title: '设备搜索中',
|
||||
})
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
allowDuplicatesKey: true,
|
||||
success: res => {
|
||||
that.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: res => {
|
||||
wx.hideLoading()
|
||||
console.log("startBluetoothDeviceDiscovery失败", res)
|
||||
}
|
||||
});
|
||||
},
|
||||
onBluetoothDeviceFound() {
|
||||
var that = this;
|
||||
const foundDevices = []
|
||||
uni.onBluetoothDeviceFound(res => {
|
||||
res.devices.forEach(device => {
|
||||
if (!device.name && !device.localName) {
|
||||
return
|
||||
}
|
||||
if (device.name.indexOf('AiLink_') != -1) {
|
||||
const foundDevices = that.devices
|
||||
const idx = that.$tools.inArray(foundDevices, "deviceId", device.deviceId)
|
||||
let buff = device.advertisData.slice(-6)
|
||||
device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址
|
||||
let tempMac = Array.from(device.mac)
|
||||
tempMac.reverse()
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
that.deviceId = device.deviceId
|
||||
that.macAddr = device.macAddr
|
||||
console.log("device0", device.macAddr, that.deviceId, )
|
||||
if (idx === -1) {
|
||||
that.devices.push(device);
|
||||
} else {
|
||||
that.devices[idx] = device
|
||||
}
|
||||
that.popup = true
|
||||
return
|
||||
}
|
||||
if (device.advertisServiceUUIDs[0].indexOf("F0A0") !== -1) {
|
||||
const foundDevices = that.devices
|
||||
const idx = that.$tools.inArray(foundDevices, "deviceId", device.deviceId)
|
||||
let buffer = device.advertisData.slice(0, 8)
|
||||
device.mac = new Uint8Array(buffer)
|
||||
let tempMac = Array.from(device.mac)
|
||||
tempMac.reverse()
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
that.deviceId = device.deviceId;
|
||||
that.macAddr = device.macAddr
|
||||
console.log("device1", device.macAddr, that.deviceId)
|
||||
if (idx === -1) {
|
||||
that.devices.push(device);
|
||||
} else {
|
||||
that.devices[idx] = device
|
||||
}
|
||||
that.popup = true
|
||||
return
|
||||
}
|
||||
})
|
||||
});
|
||||
that.handleMyTime()
|
||||
},
|
||||
handleMyTime() {
|
||||
var that = this;
|
||||
myTime = setTimeout(function() {
|
||||
if (!that.devices.length) {
|
||||
clearTimeout(myTime);
|
||||
wx.hideLoading()
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请确定蓝牙和手机位置信息已打开!请确定设备已开机;ios系统需打开设置——>应用——>微信里的蓝牙权限!是否继续?',
|
||||
cancelText: "取消",
|
||||
confirmText: "继续",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
} else {
|
||||
that.$tools.msg("您已取消操作")
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
clearTimeout(myTime);
|
||||
that.stopBluetoothDevicesDiscovery()
|
||||
}
|
||||
}, 30000);
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery() {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log("停止搜索蓝牙设备", e)
|
||||
},
|
||||
});
|
||||
},
|
||||
// 连接蓝牙
|
||||
createBLEConnection(e) {
|
||||
let that = this;
|
||||
that.stopBluetoothDevicesDiscovery()
|
||||
that.macAddr = e.macAddr
|
||||
that.getCode()
|
||||
},
|
||||
getCode() {
|
||||
let that = this;
|
||||
clearTimeout(myTime);
|
||||
wx.hideLoading()
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '是否激活该设备?',
|
||||
cancelText: "取消",
|
||||
confirmText: "确定",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
that.getActive()
|
||||
} else {
|
||||
that.$tools.msg("您已取消操作")
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getActive() {
|
||||
let that = this
|
||||
that.$model.getdevactive({
|
||||
code: that.code,
|
||||
sn: that.macAddr
|
||||
}).then(res => {
|
||||
that.$tools.msg(res.message)
|
||||
that.closeBluetoothAdapter()
|
||||
that.closeBLEConnection()
|
||||
that.devices = []
|
||||
if (res.code == 0) {
|
||||
setTimeout(function() {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index?t=" + that.devtype
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter() {
|
||||
let that = this;
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('蓝牙模块关闭成功');
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
var that = this;
|
||||
uni.closeBLEConnection({
|
||||
deviceId: that.deviceId,
|
||||
success: res => {
|
||||
console.log('断开蓝牙连接成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
min-height: 100vh;
|
||||
padding: 0;
|
||||
border-top: 66px solid #75DAD0;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.tishi {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 25px;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
padding-left: 15px;
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
text {
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 70%;
|
||||
height: 40px;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
background: #f7f7f7;
|
||||
border: 1px solid #dfdfdf;
|
||||
font-weight: bold;
|
||||
margin: auto;
|
||||
border-radius: 15px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.devices_summary {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.device_list {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: 200px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.device_item {
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
color: #999;
|
||||
border-bottom: 1px solid #dfdfdf;
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #e83a1e;
|
||||
background: #f7e4c8;
|
||||
padding: 5px 0;
|
||||
margin-top: 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,637 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<!-- 头部 -->
|
||||
<view class="header-con">
|
||||
<view class="header" v-if="token">
|
||||
<view class="left">
|
||||
<image :src="user.headimg" class="headimage mr-10" @click="handleDrawer"></image>
|
||||
<view>
|
||||
<view class="name" @click="handleDrawer">
|
||||
<text class="overflow">{{user.name}}</text>
|
||||
<icon class="iconfont icon-yqfqiehuan"></icon>
|
||||
</view>
|
||||
<view class="age">
|
||||
<view>
|
||||
性别:{{!user.sex?"未知":user.sex==1?'男':'女'}}
|
||||
</view>
|
||||
<view>
|
||||
年龄:{{user.mage?user.mage:"0岁"}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="celiang_r" @click="handleBluetoothClick">
|
||||
<icon class="t-icon t-icon-tizhongcheng"></icon>
|
||||
<text>上秤测量</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header2" v-else @click="handleLogin">
|
||||
<view class="text"><text>登录</text>查看更多信息</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 提示
|
||||
<view class="mt-15" v-show="MeasureResult&&MeasureResult.muscle==0">
|
||||
<view class="unusual">体脂测量异常,请重新测量</view>
|
||||
</view> -->
|
||||
<!-- 工具 -->
|
||||
<view class="tools_l">
|
||||
<view v-for="(item,index) in toollist" :key="index" class="list" @click="clickTool(item.id)">
|
||||
<image :src="item.icon"></image>
|
||||
<view class="text">{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 报告 -->
|
||||
<view class="myinfo myinfoPage borderT15" v-if="infoList.length">
|
||||
<view class="h2">
|
||||
<view><text></text>健康评分</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view class="left">
|
||||
<view class="circleprogress">
|
||||
<view class="wrapper">
|
||||
<view class="leftprogress" :style="{ width: MeasureResult.cmi + '%'}">
|
||||
</view>
|
||||
</view>
|
||||
<view class="fen">
|
||||
<view>{{MeasureResult.cmi}}</view>分
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="item">
|
||||
<view><text>{{MeasureResult.height}}</text>cm</view>
|
||||
<view class="tivon">身高</image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view><text>{{MeasureResult.weight}}</text>kg</view>
|
||||
<view>体重</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view><text>{{MeasureResult.bodyage}}</text>岁</view>
|
||||
<view>体龄</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view><text class="f-15">{{MeasureResult.body}}</text></view>
|
||||
<view>体型</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="myinfo myinfoPage borderT15">
|
||||
<view class="h2">
|
||||
<view><text></text>健康分析</view>
|
||||
<view class="more" v-if="infoList.length">测量时间:{{user.lasthearttime}}</view>
|
||||
</view>
|
||||
<view v-if="infoList.length">
|
||||
<view class="box1">
|
||||
<view class="list" v-for="(item,index) in infoList" :key="index" @click="handleToggle(index)">
|
||||
<view class="block">
|
||||
<view class="name">
|
||||
<icon class="t-icon iconfont" :class="'t-icon-'+item.key"></icon>
|
||||
{{item.title}}
|
||||
</view>
|
||||
<view class="val" v-if="item.title!='肥胖等级'">
|
||||
{{item.fvalue?item.fvalue:'0'}}{{item.dw}}
|
||||
</view>
|
||||
<view class="val0" v-else>{{item.fevaluation}}</view>
|
||||
<view class="level" v-if="item.title!='肥胖等级'">
|
||||
<view class="btnf" :style="{backgroundColor:item.color}">{{item.fevaluation}}</view>
|
||||
</view>
|
||||
<view class="icon">
|
||||
<icon class="iconfont icon-arrow-down" v-if="item.desc"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="desc" v-if="item.showCon">
|
||||
<view v-if="item.desc">{{item.desc}}</view>
|
||||
<view class="statuevue" v-if="item.slist">
|
||||
<view class="bi" v-if="item.title!='基础代谢'">
|
||||
<view class="item" v-for="(ite , ind) in item.slist" :key="ind"
|
||||
:style="{backgroundColor:ite.color}">
|
||||
<view class="span1">{{ite.text}}</view>
|
||||
<view v-if="ite.text==item.fevaluation&&item.fvalue>ite.maxvalue"
|
||||
style="right: 10px" class="peobox">
|
||||
<view class="xx"></view>
|
||||
</view>
|
||||
<view v-if="ite.text==item.fevaluation&&item.fvalue<=ite.maxvalue"
|
||||
:style="'left:'+item.leftval+'rem'" class="peobox">
|
||||
<view class="xx"></view>
|
||||
</view>
|
||||
<view class="span" v-if="ind<item.slist.length-1">{{ite.maxvalue}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="kcalClass">
|
||||
标准值:{{item.slist[0].maxvalue}}kcal
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="nolist">
|
||||
<icon class="iconfont icon-zanwu"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="introction" v-if="infoList.length">
|
||||
<icon class="t-icon t-icon-tishi"></icon>
|
||||
<span>此测量数据仅供参考,不可代替医学专业测试!</span>
|
||||
</view>
|
||||
<!-- 提醒设置 -->
|
||||
<view class="tipList borderRadius borderT15 mb-15">
|
||||
<view class="h2">
|
||||
<view><text></text>提醒设置</view>
|
||||
</view>
|
||||
<view class="item_box">
|
||||
<view class="item_box_tips" v-for="(text,id) in checkList" :key="id" @click="switch1Change(text.index)">
|
||||
{{text.title}}
|
||||
<image class="iconfont"
|
||||
:src="isShowEle == text.index?'../../static/switch-off.png':'../../static/switch-ON.png'" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- banner -->
|
||||
<view class="f_banner borderT15" v-if="fimages.length">
|
||||
<swiper class="swiper" indicator-dots="true" autoplay="true">
|
||||
<swiper-item v-for="(image, index) in fimages" :key="index" @click="detail(image)">
|
||||
<image :src="image.headimg" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="endtext" v-if="!lastPage || page >= lastPage">—— 到底了,看看别的吧 ——</view>
|
||||
<!-- denglu -->
|
||||
<userLogin></userLogin>
|
||||
<!-- 手动记录 -->
|
||||
<manuaRecord></manuaRecord>
|
||||
<!-- 左侧 -->
|
||||
<leftdrawer></leftdrawer>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
import userLogin from '@/components/userLogin.vue'
|
||||
import leftdrawer from "@/components/drawer/drawer.vue"
|
||||
import manuaRecord from '@/components/target/manuaRecord.vue';
|
||||
export default {
|
||||
components: {
|
||||
leftdrawer,
|
||||
userLogin,
|
||||
manuaRecord
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "MeasureResult"]),
|
||||
},
|
||||
onLoad(options) {
|
||||
let that = this;
|
||||
that.token = uni.getStorageSync('token')
|
||||
if (options && options.t) {
|
||||
that.devType = options.t
|
||||
that.deviceId = options.sn
|
||||
}
|
||||
that.login()
|
||||
|
||||
},
|
||||
onShow() {
|
||||
this.token = uni.getStorageSync('token')
|
||||
},
|
||||
onTabItemTap() {
|
||||
this.$store.commit("changeDrawe", false)
|
||||
this.$store.commit("changeRecord", false);
|
||||
},
|
||||
watch: {
|
||||
MeasureResult() {
|
||||
this.handleToggle(0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
login() {
|
||||
let that = this
|
||||
uni.login({
|
||||
success(res) {
|
||||
if (res.code) {
|
||||
if (res.errMsg = "login:ok") {
|
||||
that.$model.onlogin({
|
||||
code: res.code,
|
||||
}).then(res => {
|
||||
if (res.code == 2) {
|
||||
uni.clearStorageSync()
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('changeUser')
|
||||
that.$store.commit("changeLogout", false);
|
||||
uni.setStorageSync('tenantid', res.data.tenantid)
|
||||
uni.setStorageSync('sessionid', res.data.sessionid)
|
||||
uni.setStorageSync('iswxphone', res.data.iswxphone)
|
||||
return
|
||||
}
|
||||
if (res.code == 0) {
|
||||
that.token = res.data.token
|
||||
uni.setStorageSync('token', res.data.token)
|
||||
uni.setStorageSync('tenantid', res.data.tenantid)
|
||||
uni.setStorageSync('sessionid', res.data.sessionid)
|
||||
uni.setStorageSync('iswxphone', res.data.iswxphone)
|
||||
uni.setStorageSync('refreshtoken', res.data.refreshtoken)
|
||||
that.getFamilyList()
|
||||
}
|
||||
}).catch(e => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getFamilyList() {
|
||||
let that = this
|
||||
that.$model.getFamilyList({}).then(res => {
|
||||
that.$store.commit("changeFamilay", res)
|
||||
that.$store.dispatch("getUserInfo", {
|
||||
familyid: res[0].familyid
|
||||
})
|
||||
that.$store.dispatch("getResult", {
|
||||
birthday: res[0].birthday,
|
||||
familyid: res[0].familyid,
|
||||
height: res[0].height,
|
||||
sex: res[0].sex,
|
||||
})
|
||||
that.GetTplList()
|
||||
that.GetSubscribeInfo()
|
||||
// that.getBannerList()
|
||||
}).catch(e => {})
|
||||
},
|
||||
//消息订阅状态
|
||||
GetSubscribeInfo() {
|
||||
let that = this
|
||||
that.$model.GetSubscribeInfo({}).then(res => {
|
||||
if (res.code == 0) {
|
||||
console.log("获取消息订阅状态", res)
|
||||
that.isShowEle = res.data.type
|
||||
}
|
||||
})
|
||||
},
|
||||
//消息模板列表
|
||||
GetTplList() {
|
||||
let that = this
|
||||
that.$model.GetTplList({}).then(res => {
|
||||
if (res.code == 0) {
|
||||
res.data.forEach(item => {
|
||||
that.tmplIdList.push(item.id)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
//消息提醒
|
||||
switch1Change(ind) {
|
||||
let that = this
|
||||
if (that.isShowEle != ind) { //允许提醒
|
||||
wx.requestSubscribeMessage({
|
||||
tmplIds: that.tmplIdList,
|
||||
success(res) {
|
||||
let list = {}
|
||||
let subList = []
|
||||
that.tmplIdList.forEach(item => {
|
||||
list = {
|
||||
"tplId": item,
|
||||
"status": res[item],
|
||||
}
|
||||
})
|
||||
subList.push(list)
|
||||
that.$model.GetSubscribe({
|
||||
type: ind,
|
||||
list: subList,
|
||||
}).then(res => {
|
||||
console.log("res", res)
|
||||
if (res.code != 0) return
|
||||
that.isShowEle = ind
|
||||
})
|
||||
},
|
||||
fail(res) {
|
||||
console.log("res失败", res)
|
||||
that.$tools.msg("订阅失败")
|
||||
}
|
||||
})
|
||||
} else { //取消提醒
|
||||
that.$model.Getunsubscribe({
|
||||
type: 1,
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
that.$tools.msg("取消提醒成功")
|
||||
that.isShowEle = 0
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
// 轮播
|
||||
getBannerList() {
|
||||
this.$model.GetAdBannerList({
|
||||
page: 1,
|
||||
pagesize: 10,
|
||||
}).then(res => {
|
||||
this.fimages = res.data.items
|
||||
})
|
||||
},
|
||||
// 上称测量
|
||||
handleBluetoothClick() {
|
||||
let that = this
|
||||
if (!that.token) {
|
||||
that.$store.commit("changeUserLogin", true)
|
||||
return
|
||||
}
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
that.$store.commit("changeBluetooth", true);
|
||||
if (that.devType && that.deviceId) {
|
||||
that.$tools.handlePages(that.devType, that.deviceId)
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: "/pages/search/devType"
|
||||
})
|
||||
console.log('初始化蓝牙成功:' + e.errMsg);
|
||||
},
|
||||
fail: err => {
|
||||
console.log('初始化蓝牙失败:' + err.errMsg);
|
||||
return this.$tools.getBluetoothAdapter(err)
|
||||
}
|
||||
});
|
||||
},
|
||||
// 切换
|
||||
handleToggle(index) {
|
||||
let that = this
|
||||
if (!that.MeasureResult) return
|
||||
let str = this.weightInfo.infoList(that.MeasureResult).slice(1, 14)
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (i == index) {
|
||||
str[i].showCon = !str[i].showCon
|
||||
} else {
|
||||
str[i].showCon = false
|
||||
}
|
||||
}
|
||||
that.infoList = this.weightInfo.infoList(that.MeasureResult).slice(1, 14)
|
||||
},
|
||||
// 工具
|
||||
clickTool(ind) {
|
||||
let that = this
|
||||
if (!that.token) {
|
||||
that.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
if (ind == 0) {
|
||||
that.$store.commit("changeRecord", true)
|
||||
return
|
||||
}
|
||||
if (ind == 1) {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/survey/survey"
|
||||
})
|
||||
return
|
||||
}
|
||||
if (ind == 2) {
|
||||
uni.navigateToMiniProgram({
|
||||
appId: 'wx3e83b37ba682faf5',
|
||||
path: 'pages/index/index',
|
||||
extraData: {},
|
||||
})
|
||||
return
|
||||
}
|
||||
if (ind == 3) {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/me/history"
|
||||
})
|
||||
return
|
||||
}
|
||||
},
|
||||
|
||||
detail(e) {
|
||||
if (e.type == 1) {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/zixun/detail?id=" + e.id
|
||||
})
|
||||
return
|
||||
}
|
||||
if (e.type == 2) {
|
||||
uni.navigateTo({
|
||||
url: "/pageTwo/zixun/detail?url=" + e.content
|
||||
})
|
||||
return
|
||||
|
||||
}
|
||||
if (e.type == 3) {
|
||||
uni.navigateToMiniProgram({
|
||||
appId: e.content,
|
||||
path: '',
|
||||
extraData: {},
|
||||
})
|
||||
return
|
||||
}
|
||||
},
|
||||
// 登录
|
||||
handleLogin() {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
},
|
||||
handleDrawer() {
|
||||
this.$store.commit("changeDrawe", true);
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fimages: [],
|
||||
token: null,
|
||||
devType: "",
|
||||
deviceId: "",
|
||||
isShowEle: 0,
|
||||
infoList: [],
|
||||
tmplIdList: [],
|
||||
toollist: [{
|
||||
icon: '/static/tool1.png',
|
||||
title: '手动记录',
|
||||
id: 0
|
||||
}, {
|
||||
icon: '/static/tool2.png',
|
||||
title: '体质评估',
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
icon: '/static/tool3.png',
|
||||
title: '儿童测量',
|
||||
id: 2
|
||||
},
|
||||
{
|
||||
icon: '/static/tool4.png',
|
||||
title: '历史记录',
|
||||
id: 3
|
||||
},
|
||||
|
||||
],
|
||||
checkList: [{
|
||||
title: '每周提醒',
|
||||
index: 1,
|
||||
},
|
||||
{
|
||||
title: '每月提醒',
|
||||
index: 2,
|
||||
},
|
||||
{
|
||||
title: '半年提醒',
|
||||
index: 3,
|
||||
},
|
||||
{
|
||||
title: '一年提醒',
|
||||
index: 4,
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
margin-top: 110px;
|
||||
background-color: #f7f7f7;
|
||||
padding-bottom: 15px;
|
||||
|
||||
// 工具
|
||||
.tools_l {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 10px;
|
||||
background: #fff;
|
||||
justify-content: space-between;
|
||||
|
||||
.list {
|
||||
width: 25%;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.text {
|
||||
margin-top: 5px;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
.myinfo {
|
||||
background: #fff;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
// 消息提醒
|
||||
|
||||
.tipList {
|
||||
background: #fff;
|
||||
margin-top: 10px;
|
||||
|
||||
.item_box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
.item_box_tips {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.t-icon,
|
||||
.iconfont {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
:nth-child(even).item_box_tips {
|
||||
text-align: right;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
// 标题
|
||||
.h2 {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
padding: 10px 15px;
|
||||
font-size: 32rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
background: $btncolor;
|
||||
width: 8px;
|
||||
height: 12px;
|
||||
margin-right: 5px;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
// banner
|
||||
.f_banner {
|
||||
width: 100%;
|
||||
height: 330rpx;
|
||||
margin-top: 30rpx;
|
||||
bottom: 52px;
|
||||
|
||||
/deep/swiper {
|
||||
height: 330rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.unusual {
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
color: #e83a1e;
|
||||
background: #f7e4c8;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.introction {
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
margin-left: 15px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
|
||||
.t-icon {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-right: 5px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.val0 {
|
||||
position: absolute;
|
||||
left: 40%;
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class="header-con">
|
||||
<view class="header" v-if="token">
|
||||
<image :src="user.headimg" class="headimage" />
|
||||
<text>{{user.name||user.name}}</text>
|
||||
</view>
|
||||
<view class="header2" v-else @click="handleLogin">
|
||||
<view class="text"><text>登录</text>查看更多信息</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 列表 -->
|
||||
<view class="infolist">
|
||||
<view class="item borderRadius" @click="handleEditClick">
|
||||
<view class="left">
|
||||
性别
|
||||
</view>
|
||||
<view class="right"><text>{{user.sex==0?"未知":user.sex==1?'男':'女'}}</text>
|
||||
<icon class="t-icon t-icon-bianji3"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item borderRadius" @click="handleEditClick">
|
||||
<view class="left">
|
||||
年龄(岁)
|
||||
</view>
|
||||
<view class="right"><text>{{user.age?user.age:user.mage?user.mage:0}}</text>
|
||||
<icon class="t-icon t-icon-bianji3"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item borderRadius" @click="handleEditClick">
|
||||
<view class="left">
|
||||
身高(cm)
|
||||
</view>
|
||||
<view class="right"><text>{{user.height?user.height:0}}</text>
|
||||
<icon class="t-icon t-icon-bianji3"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="wxlist borderRadius">
|
||||
<view class="list" @tap="navTo('/pageTwo/me/manage')">
|
||||
<view class="item border-bottom">
|
||||
<view class="left">
|
||||
<i class="t-icon t-icon-shoucang"></i>
|
||||
<view class="name">成员管理</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<icon class="icon iconfont icon-arrow-right" color="#999"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="list" @tap="navTo('/pageTwo/me/history')">
|
||||
<view class="item border-bottom">
|
||||
<view class="left">
|
||||
<i class="t-icon t-icon-gonglve"></i>
|
||||
<view class="name">历史记录</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<icon class="icon iconfont icon-arrow-right" color="#999"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="list" @tap="navTo('/pageTwo/me/feedBack')">
|
||||
<view class="item border-bottom">
|
||||
<view class="left">
|
||||
<i class="t-icon t-icon-pinglun"></i>
|
||||
<view class="name">意见反馈</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<icon class="icon iconfont icon-arrow-right" color="#999"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="list" @click="handleClick(1)">
|
||||
<view class="item border-bottom">
|
||||
<view class="left">
|
||||
<icon class="t-icon t-icon-shouhou"></icon>
|
||||
<view class="name">设备管理</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<icon class="icon iconfont icon-arrow-right" color="#999"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- -->
|
||||
<view class="list" @click="handleClick(0)">
|
||||
<view class="item border-bottom">
|
||||
<view class="left">
|
||||
<icon class="t-icon t-icon-hezuo"></icon>
|
||||
<view class="name">儿童测量</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<icon class="icon iconfont icon-arrow-right" color="#999"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn ml-15 mr-15" v-if="token" @click="handleOutLogin">退出登录</view>
|
||||
<SignUp></SignUp>
|
||||
<userPopup></userPopup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
import SignUp from '@/components/signup/signup.vue';
|
||||
import userPopup from '@/components/userLogin.vue'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
userPopup,
|
||||
SignUp,
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
},
|
||||
onTabItemTap() {
|
||||
this.$store.commit("changeEdit", false);
|
||||
},
|
||||
onLoad() {
|
||||
this.token = uni.getStorageSync("token")
|
||||
},
|
||||
methods: {
|
||||
handleLogin() {
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
},
|
||||
handleOutLogin() {
|
||||
let that = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '是否退出登录?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
that.$model.getoutlogin({
|
||||
sessionid: uni.getStorageSync('sessionid')
|
||||
}).then((res) => {
|
||||
that.$tools.msg(res.message)
|
||||
if (res.code != 0) return
|
||||
console.log('确定退出', res)
|
||||
uni.clearStorageSync()
|
||||
uni.setStorageSync('sessionid', null)
|
||||
that.$store.commit("changeLogout", false);
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
that.$tools.msg("您已取消操作!");
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
handleClick(ind) {
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
// 儿童版
|
||||
if (ind == 0) {
|
||||
uni.navigateToMiniProgram({
|
||||
appId: 'wx3e83b37ba682faf5',
|
||||
path: 'pages/index/index',
|
||||
extraData: {},
|
||||
})
|
||||
return
|
||||
}
|
||||
// 设备管理小程序
|
||||
if (ind == 1) {
|
||||
uni.navigateToMiniProgram({
|
||||
appId: 'wx6f48cc32c5c0a4a2',
|
||||
path: 'pages/index/index',
|
||||
extraData: {},
|
||||
})
|
||||
return
|
||||
}
|
||||
},
|
||||
navTo(url) {
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
handleEditClick() {
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
this.$store.commit("changeEdit", true);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped="scoped" lang="scss">
|
||||
.content {
|
||||
min-height: 100vh;
|
||||
margin-top: 110px;
|
||||
}
|
||||
|
||||
.header-con {
|
||||
height: 95px !important;
|
||||
}
|
||||
|
||||
.wxlist {
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin: 0 15px;
|
||||
padding: 0 15px;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
|
||||
.item {
|
||||
width: auto;
|
||||
font-size: 14px;
|
||||
line-height: 55px;
|
||||
height: 55px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
// border-bottom: 1px solid #dfdfdf;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
|
||||
.name {
|
||||
float: left;
|
||||
color: #333;
|
||||
position: absolute;
|
||||
left: 27px;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.infolist {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 15px;
|
||||
|
||||
.item {
|
||||
width: 30%;
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 5px;
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
icon {
|
||||
position: absolute;
|
||||
right: 7px;
|
||||
bottom: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: auto;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
/deep/ .header {
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/deep/ .header text {
|
||||
background: inherit;
|
||||
border: none;
|
||||
width: 100%;
|
||||
display: block;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
margin-right: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,469 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<view class="text" @click="openBluetoothAdapter" v-if="issearch">没有搜到想要的?点击重新搜索</view>
|
||||
<view class="point-area">
|
||||
<view class="point point-10"></view>
|
||||
<view class="point point-40"></view>
|
||||
<view class="point point-80"></view>
|
||||
<view class="point point-100"></view>
|
||||
<view class="point point-120"></view>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view class="item" v-for="(item,index) in devList" :key="index" @click="handleWeight(item)">
|
||||
<image :src="item.img"></image>
|
||||
<text>{{item.faccode}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips" v-if="isdevTip">
|
||||
<view>提示:</view>
|
||||
<text>1.请确保设备是已激活</text>
|
||||
<text>2.请确保设备是开机状态</text>
|
||||
<text>3.请确定手机蓝牙、位置信息已打开</text>
|
||||
<text>4.ios系统需打开设置—>应用—>微信里的蓝牙权限</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let that;
|
||||
let myTime;
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
Unload: false,
|
||||
issearch: false,
|
||||
isdevTip: false,
|
||||
devList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "isConnected", "isBluetoothTyle"]),
|
||||
},
|
||||
onLoad() {
|
||||
that = this
|
||||
that.openBluetoothAdapter()
|
||||
that.onBLEConnectionStateChange()
|
||||
uni.onBluetoothAdapterStateChange(function(res) {
|
||||
that.$store.commit("changeBluetooth", res.available);
|
||||
})
|
||||
},
|
||||
onUnload: function() {
|
||||
let that = this
|
||||
if (!that.Unload) {
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
console.log("搜索页返回")
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isBluetoothTyle: function() {
|
||||
let that = this
|
||||
if (!that.isBluetoothTyle) {
|
||||
that.issearch = true
|
||||
that.isdevTip = true
|
||||
that.devList = []
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
that.stopBluetoothDevicesDiscovery()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化蓝牙
|
||||
openBluetoothAdapter() {
|
||||
let that = this
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
console.log("蓝牙初始化成功")
|
||||
that.issearch = false
|
||||
that.isdevTip = false
|
||||
that.devList = []
|
||||
that.startBluetoothDeviceDiscovery()
|
||||
},
|
||||
fail: e => {
|
||||
that.$tools.msg("请打开蓝牙!安卓系统需打开蓝牙、定位权限;ios系统需打开设置——>应用——>微信里的蓝牙权限!")
|
||||
}
|
||||
});
|
||||
},
|
||||
// 监听蓝牙连接状态
|
||||
onBLEConnectionStateChange() {
|
||||
let that = this
|
||||
uni.onBLEConnectionStateChange(function(res) {
|
||||
console.log("蓝牙连接状态", res.connected)
|
||||
that.$store.commit("changeConnected", res.connected);
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery() {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log("停止搜索蓝牙设备", e)
|
||||
},
|
||||
});
|
||||
},
|
||||
// 开始搜寻附近的蓝牙外围设备
|
||||
startBluetoothDeviceDiscovery() {
|
||||
let that = this
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
// allowDuplicatesKey: false, //是否允许重复上报同一设备
|
||||
success: res => {
|
||||
that.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: res => {
|
||||
that.$tools.msg("请打开蓝牙!安卓系统需打开蓝牙、定位权限;ios系统需打开设置——>应用——>微信里的蓝牙权限!")
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
var that = this;
|
||||
uni.onBluetoothDeviceFound(res => {
|
||||
res.devices.forEach(device => {
|
||||
if (!device.name && !device.localName) {
|
||||
return
|
||||
}
|
||||
if (device.advertisServiceUUIDs[0].indexOf("F0A0") !== -1) {
|
||||
let buffer = device.advertisData.slice(0, 8)
|
||||
device.mac = new Uint8Array(buffer)
|
||||
let tempMac = Array.from(device.mac)
|
||||
tempMac.reverse()
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
if (device.macAddr != "") {
|
||||
that.handleDevType(device.macAddr)
|
||||
}
|
||||
return
|
||||
}
|
||||
let buff = device.advertisData.slice(-6)
|
||||
device.mac = new Uint8Array(buff)
|
||||
let tempMac = Array.from(device.mac)
|
||||
if (device.name.indexOf('My') == -1) {
|
||||
tempMac.reverse()
|
||||
}
|
||||
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
|
||||
if (device.macAddr != "") {
|
||||
that.handleDevType(device.macAddr)
|
||||
}
|
||||
})
|
||||
});
|
||||
that.handleMyTime()
|
||||
},
|
||||
handleMyTime() {
|
||||
var that = this;
|
||||
myTime = setTimeout(function() {
|
||||
if (!that.devList.length) {
|
||||
that.isdevTip = true
|
||||
that.devList = []
|
||||
}
|
||||
that.issearch = true
|
||||
clearTimeout(myTime);
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
}, 30000);
|
||||
},
|
||||
// 排查设备
|
||||
handleDevType(sn) {
|
||||
that = this
|
||||
that.$model.getdevdetail({
|
||||
sn: sn
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
res.data.deviceId = sn
|
||||
that.devList.push(res.data);
|
||||
}
|
||||
})
|
||||
},
|
||||
handleWeight(item) {
|
||||
let that = this
|
||||
that.Unload = true
|
||||
clearTimeout(myTime);
|
||||
if (item.type != 4 || item.type != 5 || item.type != 16) {
|
||||
that.stopBluetoothDevicesDiscovery()
|
||||
}
|
||||
that.$tools.handlePages(item.type, item.deviceId)
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter() {
|
||||
let that = this;
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('蓝牙模块关闭成功');
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
var that = this;
|
||||
uni.closeBLEConnection({
|
||||
success: res => {
|
||||
console.log('断开蓝牙连接成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
handleBack() {
|
||||
let that = this
|
||||
that.Unload = true
|
||||
that.stopBluetoothDevicesDiscovery() //取消蓝牙搜索
|
||||
that.closeBLEConnection()
|
||||
that.closeBluetoothAdapter()
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.text {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 16px;
|
||||
color: $greencolor;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tips {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 15px;
|
||||
line-height: 24px;
|
||||
|
||||
view {
|
||||
font-size: 14px;
|
||||
color: $greencolor;
|
||||
font-weight: bold;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin-left: 20px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
width: 30%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
left: 55%;
|
||||
top: -10px;
|
||||
|
||||
image {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
text {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.item:nth-of-type(2) {
|
||||
left: calc(55% - 60px);
|
||||
top: 50px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(3) {
|
||||
left: calc(50% - 140px);
|
||||
top: 90px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(4) {
|
||||
left: calc(61% + 20px);
|
||||
top: 70px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(5) {
|
||||
left: 20%;
|
||||
top: -100px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(6) {
|
||||
left: calc(20% - 16px);
|
||||
top: -38px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(7) {
|
||||
left: 0;
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(8) {
|
||||
left: calc(20% + 75px);
|
||||
top: -150px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(9) {
|
||||
left: calc(20% + 96px);
|
||||
top: -80px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(10) {
|
||||
left: 37px;
|
||||
top: -170px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(11) {
|
||||
left: calc(20% + 75px);
|
||||
top: 130px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(12) {
|
||||
left: -10px;
|
||||
top: -104px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(13) {
|
||||
left: calc(47% + 75px);
|
||||
top: -150px;
|
||||
}
|
||||
|
||||
.item:nth-of-type(14) {
|
||||
left: calc(53% + 75px);
|
||||
top: -50px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// 中心园
|
||||
.container::after {
|
||||
content: "";
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background-color: #fbb780;
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
|
||||
}
|
||||
|
||||
/* 定义范围*/
|
||||
.point-area {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
width: 400rpx;
|
||||
height: 400rpx;
|
||||
transition: opacity 0.5s ease-out;
|
||||
}
|
||||
|
||||
.point-10,
|
||||
.point-40,
|
||||
.point-80,
|
||||
.point-100,
|
||||
.point-120 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.point-10:after,
|
||||
.point-40:after,
|
||||
.point-80:after,
|
||||
.point-100:after,
|
||||
.point-120:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
border: 1px solid #f7cb6b;
|
||||
animation-play-state: paused;
|
||||
-webkit-animation-play-state: paused;
|
||||
}
|
||||
|
||||
.point-10:after {
|
||||
content: '';
|
||||
animation: ripple 3000ms linear 0ms infinite;
|
||||
}
|
||||
|
||||
.point-40:after {
|
||||
content: '';
|
||||
animation: ripple 3000ms linear 600ms infinite;
|
||||
|
||||
}
|
||||
|
||||
.point-80:after {
|
||||
content: '';
|
||||
animation: ripple 3000ms linear 1200ms infinite;
|
||||
}
|
||||
|
||||
.point-100:after {
|
||||
content: '';
|
||||
animation: ripple 3000ms linear 1800ms infinite;
|
||||
}
|
||||
|
||||
.point-120:after {
|
||||
content: '';
|
||||
animation: ripple 3000ms linear 2400ms infinite;
|
||||
}
|
||||
|
||||
|
||||
@keyframes ripple {
|
||||
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.1);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.2;
|
||||
transform: scale(2.2);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<!-- 时间选择 -->
|
||||
<view class="TrendPage">
|
||||
<view class="TrendTime">
|
||||
<view class="boxTime">
|
||||
<view class="one">
|
||||
<picker mode="date" class="f-l" :value="startTime?startTime:startDate" @change="handStartTimeH">
|
||||
<view class="uni-input">{{startTime?startTime:startDate}}
|
||||
<icon class="iconfont iconDown"></icon>
|
||||
</view>
|
||||
</picker>
|
||||
|
||||
<picker mode="date" :end="endDate" class="f-r" :value="endDate" @change="handEndTimeH">
|
||||
<view class="uni-input">~ {{endTime?endTime:endDate}}
|
||||
<icon class="iconfont iconDown"></icon>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="tow" @click="handAllTime(0)" :class="{style:active==0}">
|
||||
近3月
|
||||
</view>
|
||||
<view class="tow" @click="handAllTime(1)" :class="{style:active==1}">
|
||||
近半年
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 曲线图 -->
|
||||
<view class="box boxList">
|
||||
<view class="listC">
|
||||
<view :class="{active:index==active1}" class="name" v-for="(item,index) in weightList" :key="index"
|
||||
@click="showbox(index)">
|
||||
{{item.title}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="blockC">
|
||||
<view v-if="lineData&&lineData.categories.length&&handTrue">
|
||||
<qiun-data-charts type="area" :chartData="lineData" :canvas2d="true" canvasId="charts09"
|
||||
:cHeight="480" :cWidth="640" :animation="false"
|
||||
:opts="{enableScroll:true,xAxis:{scrollShow:false,itemCount:3}}" :ontouch="true" />
|
||||
</view>
|
||||
<view class="nolist" v-else>
|
||||
<icon class="iconfont icon-zanwu"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 目标-->
|
||||
<view class="box">
|
||||
<view class="data">
|
||||
<view class="item" @click="handleClick(0)">
|
||||
<view class="val">{{userInfo.targetweight?userInfo.targetweight:0}}<text>kg</text>
|
||||
</view>
|
||||
<view class="name">目标体重<icon class="t-icon t-icon-bianji3"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="val">{{userInfo.totalweight?Math.abs(userInfo.totalweight):0}}<text>kg</text>
|
||||
</view>
|
||||
<view class="name" v-if="Number(userInfo.totalweight)<0">累计增重</view>
|
||||
<view class="name" v-else>累计减重</view>
|
||||
</view>
|
||||
<view class="item" @click="handleClick(1)">
|
||||
<view class="val">{{userInfo.firstweight?userInfo.firstweight:0}}<text>kg</text>
|
||||
</view>
|
||||
<view class="name">初始体重<icon class="t-icon t-icon-bianji3"></icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="val">{{userInfo.day?userInfo.day:0}}<text>天</text></view>
|
||||
<view class="name">减重天数</view>
|
||||
</view>
|
||||
<view class="item" @click="handleClick(2)">
|
||||
<view class="val"></view>
|
||||
<view class="name">
|
||||
<icon class="iconfont icon-tianjia">手动记录</icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 手动 -->
|
||||
<manuaRecord @getList="getList"></manuaRecord>
|
||||
<!-- 初始 -->
|
||||
<firstweight></firstweight>
|
||||
<!-- 目标 -->
|
||||
<targetWeight></targetWeight>
|
||||
<!-- 登录 -->
|
||||
<userPopup></userPopup>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState
|
||||
} from "vuex";
|
||||
import userPopup from '@/components/userLogin.vue'
|
||||
import targetWeight from '@/components/target/targetWeight.vue';
|
||||
import firstweight from '@/components/target/firstweight.vue';
|
||||
import manuaRecord from '@/components/target/manuaRecord.vue';
|
||||
import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts.vue';
|
||||
export default {
|
||||
components: {
|
||||
targetWeight,
|
||||
firstweight,
|
||||
manuaRecord,
|
||||
userPopup,
|
||||
qiunDataCharts,
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "Trend"]),
|
||||
userInfo: function() {
|
||||
return this.user
|
||||
},
|
||||
endDate() {
|
||||
return this.$tools.getDate("start")
|
||||
},
|
||||
startDate() {
|
||||
return this.$tools.GetDateStr(-90);
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
let that = this
|
||||
this.token = uni.getStorageSync('token')
|
||||
this.active = 0
|
||||
this.startTime = ""
|
||||
this.endTime = ""
|
||||
that.getList(this.startDate, this.endDate)
|
||||
},
|
||||
methods: {
|
||||
getList(start, end) {
|
||||
console.log("fanhui", start, end)
|
||||
let that = this
|
||||
that.$model.getTrendList({
|
||||
familyid: uni.getStorageSync('familyid'),
|
||||
starttime: start,
|
||||
endtime: end,
|
||||
}).then(res => {
|
||||
if (res) {
|
||||
for (var i = 0; i < that.weightList.length; i++) {
|
||||
that.weightList[i].Line = res[that.weightList[i].key];
|
||||
}
|
||||
that.showbox(0)
|
||||
}
|
||||
})
|
||||
},
|
||||
showbox(index) {
|
||||
let that = this
|
||||
that.handTrue = false
|
||||
this.$nextTick(function() {
|
||||
that.handTrue = true
|
||||
that.lineData = that.weightList[index].Line
|
||||
})
|
||||
that.active1 = index
|
||||
},
|
||||
//开始
|
||||
handStartTimeH(e) {
|
||||
let that = this
|
||||
if (this.endTime) {
|
||||
if (Date.parse(e.target.value) > Date.parse(this.endTime)) {
|
||||
this.$tools.msg("请选择正确的时间")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (Date.parse(e.target.value) > Date.parse(this.endDate)) {
|
||||
this.$tools.msg("请选择正确的时间")
|
||||
return
|
||||
}
|
||||
}
|
||||
this.startTime = e.target.value
|
||||
let endtime = that.endTime ? that.endTime : that.endDate
|
||||
this.getList(that.startTime, endtime)
|
||||
},
|
||||
// 结束
|
||||
handEndTimeH(e) {
|
||||
let that = this
|
||||
if (this.startTime) {
|
||||
if (Date.parse(e.target.value) < Date.parse(this.startTime)) {
|
||||
this.$tools.msg("请选择正确的时间")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (Date.parse(e.target.value) < Date.parse(this.startDate)) {
|
||||
this.$tools.msg("请选择正确的时间")
|
||||
return
|
||||
}
|
||||
}
|
||||
this.endTime = e.target.value
|
||||
let startTime = that.startTime ? that.startTime : that.startDate
|
||||
this.getList(startTime, this.endTime)
|
||||
},
|
||||
// 日期
|
||||
handAllTime(ind) {
|
||||
let that = this
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
this.active = ind
|
||||
if (ind == 0) {
|
||||
this.startTime = that.$tools.GetDateStr(-90)
|
||||
} else {
|
||||
this.startTime = that.$tools.GetDateStr(-180)
|
||||
}
|
||||
this.getList(this.startTime, this.endDate)
|
||||
},
|
||||
handleClick(ind) {
|
||||
if (!uni.getStorageSync('token')) {
|
||||
this.$store.commit("changeUserLogin", true);
|
||||
return
|
||||
}
|
||||
if (ind == 0) {
|
||||
this.$store.commit("changeTarget", true);
|
||||
return
|
||||
}
|
||||
if (ind == 1) {
|
||||
this.$store.commit("changeFirst", true);
|
||||
return
|
||||
}
|
||||
if (ind == 2) {
|
||||
this.$store.commit("changeRecord", true);
|
||||
return
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lineData: null,
|
||||
type: null,
|
||||
active1: 0,
|
||||
weight: "",
|
||||
startTime: "",
|
||||
endTime: "",
|
||||
active: 0,
|
||||
token: null,
|
||||
handTrue: true,
|
||||
weightList: [{
|
||||
title: '体重',
|
||||
key: 'weight',
|
||||
showCon: false,
|
||||
Line: {
|
||||
"categories": [],
|
||||
"series": [{
|
||||
"color": "#fb7b92",
|
||||
"name": "体重",
|
||||
"data": []
|
||||
}]
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'BMI',
|
||||
key: 'bmi',
|
||||
Line: {
|
||||
"categories": [],
|
||||
"series": [{
|
||||
"color": "#6bb0fe",
|
||||
"name": "bmi",
|
||||
"data": []
|
||||
}]
|
||||
},
|
||||
}, {
|
||||
title: '肌肉',
|
||||
key: 'muscle',
|
||||
showCon: false,
|
||||
Line: {
|
||||
"categories": [],
|
||||
"series": [{
|
||||
"color": "#ff9f40",
|
||||
"name": "肌肉率",
|
||||
"data": []
|
||||
}]
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '脂肪',
|
||||
key: 'fat_r',
|
||||
showCon: false,
|
||||
Line: {
|
||||
"categories": [],
|
||||
"series": [{
|
||||
"color": "#3fcba7",
|
||||
"name": "脂肪率",
|
||||
"data": []
|
||||
}]
|
||||
},
|
||||
}
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.TrendTime {
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.listC {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.boxList {
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
|
||||
.list {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"description": "项目配置文件",
|
||||
"packOptions": {
|
||||
"ignore": []
|
||||
},
|
||||
"setting": {
|
||||
"bundle": false,
|
||||
"userConfirmedBundleSwitch": false,
|
||||
"urlCheck": true,
|
||||
"scopeDataCheck": false,
|
||||
"coverView": true,
|
||||
"es6": true,
|
||||
"postcss": true,
|
||||
"compileHotReLoad": false,
|
||||
"lazyloadPlaceholderEnable": false,
|
||||
"preloadBackgroundData": false,
|
||||
"minified": true,
|
||||
"autoAudits": false,
|
||||
"newFeature": false,
|
||||
"uglifyFileName": false,
|
||||
"uploadWithSourceMap": true,
|
||||
"useIsolateContext": true,
|
||||
"nodeModules": false,
|
||||
"enhance": true,
|
||||
"useMultiFrameRuntime": true,
|
||||
"useApiHook": true,
|
||||
"useApiHostProcess": true,
|
||||
"showShadowRootInWxmlPanel": true,
|
||||
"packNpmManually": false,
|
||||
"enableEngineNative": false,
|
||||
"packNpmRelationList": [],
|
||||
"minifyWXSS": true,
|
||||
"showES6CompileOption": false
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "2.20.2",
|
||||
"appid": "wx920fdb58338cc50a",
|
||||
"projectname": "miniprogram-2",
|
||||
"debugOptions": {
|
||||
"hidedInDevtools": []
|
||||
},
|
||||
"scripts": {},
|
||||
"staticServerOptions": {
|
||||
"baseURL": "",
|
||||
"servePath": ""
|
||||
},
|
||||
"isGameTourist": false,
|
||||
"condition": {
|
||||
"search": {
|
||||
"list": []
|
||||
},
|
||||
"conversation": {
|
||||
"list": []
|
||||
},
|
||||
"game": {
|
||||
"list": []
|
||||
},
|
||||
"plugin": {
|
||||
"list": []
|
||||
},
|
||||
"gamePlugin": {
|
||||
"list": []
|
||||
},
|
||||
"miniprogram": {
|
||||
"list": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
|
@ -0,0 +1,83 @@
|
|||
import model from "../tools/model.js"
|
||||
import tools from '@/tools/tools.js'
|
||||
// Action 包含异步操作(请求API方法)、回调函数提交mutaions更改state数据状态,使之可以异步
|
||||
export default {
|
||||
// 用户信息
|
||||
getUserInfo({
|
||||
commit
|
||||
},
|
||||
account) {
|
||||
return model.getUserInfo(account).then(res => {
|
||||
commit('changeUser', res.data)
|
||||
if (!res.data.height || !res.data.mage || !res.data.birthday) {
|
||||
uni.redirectTo({
|
||||
url: `/pageTwo/login/userinfo`
|
||||
})
|
||||
return
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取称重结果
|
||||
getResult({
|
||||
commit
|
||||
}, account) {
|
||||
return model.getResult(account).then((res) => {
|
||||
console.log("报告", res)
|
||||
if (res.code == 0) {
|
||||
commit('changeMeasureResult', res.data)
|
||||
} else {
|
||||
commit('changeMeasureResult', null)
|
||||
}
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
// 获取历史记录
|
||||
gethistoryList({
|
||||
commit
|
||||
}, account) {
|
||||
return model.getHistoryList(account).then((res) => {
|
||||
if (res.data && res.data.items) {
|
||||
commit('changehistoryList', res.data.items)
|
||||
} else {
|
||||
commit('changehistoryList', null)
|
||||
}
|
||||
return res
|
||||
})
|
||||
},
|
||||
//趋势
|
||||
GetBodyTrendList({
|
||||
commit
|
||||
}, account) {
|
||||
return model.GetBodyTrendList(account).then((res) => {
|
||||
if (res) {
|
||||
commit('changeTrend', res.cidata)
|
||||
}
|
||||
return res
|
||||
})
|
||||
},
|
||||
// 更新家庭成员
|
||||
getFamilyList({
|
||||
commit
|
||||
}) {
|
||||
return model.getFamilyList({
|
||||
pagenum: 20,
|
||||
pagesize: 1
|
||||
}).then((res) => {
|
||||
commit('changeFamilay', res)
|
||||
return res
|
||||
})
|
||||
},
|
||||
// 获取历史记录
|
||||
gethistoryList({
|
||||
commit
|
||||
}, account) {
|
||||
return model.getHistoryList(account).then((res) => {
|
||||
if (res.data && res.data.rows) {
|
||||
commit('changehistoryList', res.data.rows)
|
||||
} else {
|
||||
commit('changehistoryList', null)
|
||||
}
|
||||
return res
|
||||
})
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import actions from './actions.js'
|
||||
Vue.use(Vuex)
|
||||
export default new Vuex.Store({
|
||||
// state: 存储基本数据
|
||||
state: {
|
||||
user: {
|
||||
headimg: null,
|
||||
name: "",
|
||||
nickname: "",
|
||||
targetweight: 0, //目标体重
|
||||
firstweight: 0, //初始体重
|
||||
weight: 0,
|
||||
birthday: "",
|
||||
height: 0,
|
||||
age: "0",
|
||||
sex: 0,
|
||||
familyid: 0,
|
||||
mage: "",
|
||||
firstresulttime: ""
|
||||
},
|
||||
MeasureResult: {},
|
||||
isedit: false,
|
||||
isDrawe: false,
|
||||
isConnected: false,
|
||||
isBluetoothTyle: false,
|
||||
familayList: [],
|
||||
historyList: [],
|
||||
Banner: [],
|
||||
Trend: {},
|
||||
TrendPk: {},
|
||||
isTarget: false,
|
||||
isFirst: false,
|
||||
isRecord: false,
|
||||
isLogin: false,
|
||||
isLogout: true,
|
||||
},
|
||||
// mutations: Store中更改state数据状态的唯一方法(必须是同步函数)
|
||||
mutations: {
|
||||
/* 用户信息 */
|
||||
changeUser(state, newData) {
|
||||
if (newData.familyid) {
|
||||
uni.setStorageSync('familyid', newData.familyid);
|
||||
}
|
||||
Object.assign(state.user, newData)
|
||||
},
|
||||
//登录弹框
|
||||
changeUserLogin(state, newData) {
|
||||
state.isLogin = newData
|
||||
},
|
||||
//历史记录
|
||||
changehistoryList(state, newData) {
|
||||
state.historyList = newData
|
||||
},
|
||||
// 获取称重数据
|
||||
changeMeasureResult(state, newData) {
|
||||
state.MeasureResult = newData
|
||||
},
|
||||
// 信息弹框
|
||||
changeEdit(state, newData) {
|
||||
state.isedit = newData
|
||||
},
|
||||
// 目标体重
|
||||
changeTarget(state, newData) {
|
||||
state.isTarget = newData
|
||||
},
|
||||
// 初始体重
|
||||
changeFirst(state, newData) {
|
||||
state.isFirst = newData
|
||||
},
|
||||
// 手动记录
|
||||
changeRecord(state, newData) {
|
||||
state.isRecord = newData
|
||||
},
|
||||
// 左侧菜单弹框
|
||||
changeDrawe(state, newData) {
|
||||
state.isDrawe = newData
|
||||
},
|
||||
//获取家庭成员
|
||||
changeFamilay(state, newData) {
|
||||
state.familayList = newData
|
||||
},
|
||||
//蓝牙状态
|
||||
changeBluetooth(state, newData) {
|
||||
state.isBluetoothTyle = newData
|
||||
},
|
||||
// 蓝牙连接状态
|
||||
changeConnected(state, newData) {
|
||||
state.isConnected = newData
|
||||
},
|
||||
//趋势
|
||||
changeTrend(state, newData) {
|
||||
state.Trend = newData
|
||||
},
|
||||
//对比
|
||||
changeTrendPk(state, newData) {
|
||||
state.TrendPk = newData
|
||||
},
|
||||
// banner
|
||||
changeBanner(state, newData) {
|
||||
state.Banner = newData
|
||||
},
|
||||
// 退出登录
|
||||
changeLogout(state, newData) {
|
||||
if (newData == false) {
|
||||
state.user = {
|
||||
headimg: null,
|
||||
nickname: "",
|
||||
name: "",
|
||||
targetweight: 0, //目标体重
|
||||
firstweight: 0, //初始体重
|
||||
weight: 0,
|
||||
birthday: "",
|
||||
height: 0,
|
||||
age: 0,
|
||||
sex: 0,
|
||||
familyid: 0,
|
||||
firstresulttime: ""
|
||||
}
|
||||
state.Trend = null
|
||||
state.historyList = null
|
||||
state.devTypeList = null
|
||||
}
|
||||
state.isLogout = newData
|
||||
},
|
||||
|
||||
},
|
||||
// 模块化vuex
|
||||
modules: {},
|
||||
actions
|
||||
})
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
let data = [{
|
||||
title: '体重',
|
||||
showCon: false,
|
||||
key: 'weight',
|
||||
dw: 'kg',
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
color: "#ff4239",
|
||||
desc: "反映和衡量一个人健康状况的重要标志之一",
|
||||
},
|
||||
{
|
||||
title: 'BMI',
|
||||
color: "#ff4239",
|
||||
showCon: false,
|
||||
key: 'bmi',
|
||||
level: "bmilevel",
|
||||
dw: '',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
desc: 'BMI是身体质量指数,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。',
|
||||
}, {
|
||||
title: '脂肪率',
|
||||
showCon: false,
|
||||
color: "#ff4239",
|
||||
key: 'fat_r',
|
||||
level: "fat_rlevel",
|
||||
dw: '%',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
desc: '体脂率是指身体成分中,脂肪组织所占的比率。测量体脂率比单纯的只测量体重更能反映我们身体的脂肪水平(肥胖程度)。',
|
||||
},
|
||||
//
|
||||
{
|
||||
title: '脂肪量',
|
||||
key: 'fat_w',
|
||||
color: "#ff4239",
|
||||
scope: '',
|
||||
showCon: false,
|
||||
level: "fat_wlevel",
|
||||
dw: 'kg',
|
||||
leftval: 0,
|
||||
desc: '人体脂肪的重量',
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '肌肉率',
|
||||
key: 'muscle',
|
||||
showCon: false,
|
||||
color: "#ff4239",
|
||||
level: "musclelevel",
|
||||
dw: '%',
|
||||
slist: [],
|
||||
leftval: 0,
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
desc: '根据人体肌肉总量和人体体重、身高等相结合得到的人体的一个比例值,这个值的范围决定一个人的身体健康状况以及力量的多少。',
|
||||
},
|
||||
{
|
||||
title: '肌肉量',
|
||||
color: "#ff4239",
|
||||
key: 'muscleval',
|
||||
level: "musclelevel",
|
||||
showCon: false,
|
||||
dw: 'kg',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
desc: '肌肉量=实际体重*肌肉率',
|
||||
},
|
||||
{
|
||||
title: '水分',
|
||||
key: 'water',
|
||||
color: "#ff4239",
|
||||
level: "waterlevel",
|
||||
showCon: false,
|
||||
dw: '%',
|
||||
desc: '指人体内水分比例。',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '蛋白量',
|
||||
color: "#ff4239",
|
||||
level: "proteinlevel",
|
||||
key: 'proteinval',
|
||||
showCon: false,
|
||||
dw: 'kg',
|
||||
desc: '蛋白量=实际体重*蛋白率',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '骨重',
|
||||
color: "#ff4239",
|
||||
key: 'bone',
|
||||
showCon: false,
|
||||
level: "bonelevel",
|
||||
dw: '',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
desc: '单位体积内,骨组织、骨矿物质(钙、磷等)和骨基质(骨胶原、蛋白率、无机盐等等)]含量,骨量代表它们骨骼健康的情况。',
|
||||
},
|
||||
{
|
||||
title: '蛋白率',
|
||||
color: "#ff4239",
|
||||
key: 'protein',
|
||||
level: "proteinlevel",
|
||||
showCon: false,
|
||||
dw: '%',
|
||||
desc: '人体内蛋白率含量。',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '基础代谢',
|
||||
key: 'kcal',
|
||||
color: "#ff4239",
|
||||
level: "kcallevel",
|
||||
showCon: false,
|
||||
dw: 'kcal',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
desc: '指人体在清醒而又极端安静的状态下,不受肌肉活动、环境温度、食物及精神紧张等影响时的能量代谢率',
|
||||
},
|
||||
//
|
||||
|
||||
{
|
||||
title: '内脏指数',
|
||||
color: "#ff4239",
|
||||
key: 'visceral',
|
||||
showCon: false,
|
||||
level: "viscerallevel",
|
||||
dw: '',
|
||||
desc: '内脏脂肪指数',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '皮下脂肪',
|
||||
key: 'sfr',
|
||||
color: "#ff4239",
|
||||
showCon: false,
|
||||
level: "sfrlevel",
|
||||
dw: '%',
|
||||
desc: '皮下脂脂肪就是贮存于皮下的脂肪组织,人体的脂肪大约有2/3贮存在皮下组织',
|
||||
slist: [],
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '肥胖等级',
|
||||
key: 'fatlevel',
|
||||
level: "fatlevel",
|
||||
showCon: false,
|
||||
leftval: 0,
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
desc: '肥胖的程度,表现实际体重与理想体重的差距。肥胖等级是判定肥胖症的一个指标。',
|
||||
},
|
||||
//
|
||||
{
|
||||
title: '去脂体重',
|
||||
key: 'lbm',
|
||||
showCon: false,
|
||||
dw: 'kg',
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '体龄',
|
||||
key: 'bodyage',
|
||||
showCon: false,
|
||||
dw: '岁',
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
{
|
||||
title: '体型',
|
||||
key: 'body',
|
||||
level: "bodylevel",
|
||||
showCon: false,
|
||||
fvalue: null,
|
||||
svalue: null,
|
||||
fevaluation: null,
|
||||
sevaluation: null,
|
||||
vs: 0,
|
||||
num: 0,
|
||||
},
|
||||
]
|
||||
|
||||
function infoList(str) {
|
||||
let listStr = [...data];
|
||||
let leftval = 0
|
||||
if (!str) return
|
||||
for (var i = 0; i < listStr.length; i++) {
|
||||
listStr[i].fvalue = str[listStr[i].key];
|
||||
listStr[i].fevaluation = str[listStr[i].level];
|
||||
if (str.list && str.list.length) {
|
||||
for (var k = 0; k < str.list.length; k++) {
|
||||
if (listStr[i].key == str.list[k].name) {
|
||||
listStr[i].slist = str.list[k].list
|
||||
listStr[i].color = str.list[k].color
|
||||
listStr[i].fvalue = str.list[k].value
|
||||
listStr[i].fevaluation = str.list[k].level
|
||||
}
|
||||
}
|
||||
for (let j in listStr[i].slist) {
|
||||
if (listStr[i].fevaluation == listStr[i].slist[j].text) {
|
||||
listStr[i].leftval = (listStr[i].fvalue - listStr[i].slist[j].minvalue) / (listStr[i].slist[j]
|
||||
.maxvalue - listStr[i].slist[j].minvalue) * 4.2
|
||||
}
|
||||
}
|
||||
} else {
|
||||
listStr[i].slist = null
|
||||
}
|
||||
}
|
||||
return listStr
|
||||
}
|
||||
|
||||
export default {
|
||||
data,
|
||||
infoList,
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import tools from '@/tools/tools.js'
|
||||
import store from '../store'
|
||||
// 获取appid
|
||||
const accountInfo = wx.getAccountInfoSync();
|
||||
const appid = accountInfo.miniProgram.appId
|
||||
uni.setStorageSync('appid', accountInfo.miniProgram.appId)
|
||||
|
||||
const baseUrl = 'https://ttybapi.pcxbc.com';
|
||||
// const baseUrl = 'https://ybapi.pcxbc.com';
|
||||
const httpRequest = (url, method = "get", data) => {
|
||||
let httpDefaultOpts = {
|
||||
url: baseUrl + url,
|
||||
data: data,
|
||||
method: method,
|
||||
header: {
|
||||
'Authorization': "Bearer " + uni.getStorageSync('token'),
|
||||
'X-Authorization': "Bearer " + uni.getStorageSync('refreshtoken'),
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'content-type': 'application/json;charset=UTF-8',
|
||||
},
|
||||
}
|
||||
let promise = new Promise(function(resolve, reject) {
|
||||
if (httpDefaultOpts.url.indexOf("/api/device/detail") == -1) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
})
|
||||
}
|
||||
uni.request(httpDefaultOpts).then(
|
||||
(res) => {
|
||||
uni.hideLoading()
|
||||
if (res[1].data.code == 401) {
|
||||
uni.clearStorageSync()
|
||||
uni.setStorageSync('token', "")
|
||||
store.commit("changeLogout", false);
|
||||
return
|
||||
}
|
||||
if (res[1].statusCode != 200) {
|
||||
tools.msg(res[1].data.message)
|
||||
return
|
||||
}
|
||||
resolve(res[1].data)
|
||||
}
|
||||
).catch(
|
||||
(response) => {
|
||||
uni.hideLoading()
|
||||
reject(response)
|
||||
}
|
||||
)
|
||||
})
|
||||
return promise
|
||||
|
||||
};
|
||||
const get = (url, data) => {
|
||||
data.appid = appid
|
||||
return httpRequest(url, 'get', data)
|
||||
}
|
||||
|
||||
const post = (url, data) => {
|
||||
data.appid = appid
|
||||
return httpRequest(url, 'post', data)
|
||||
}
|
||||
export default {
|
||||
baseUrl,
|
||||
get,
|
||||
post
|
||||
}
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
import http from './https.js'
|
||||
export default {
|
||||
onlogin(param) { // 登录
|
||||
return http.post("/api/wxopen/onlogin", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getSendCode(param) { // 验证码
|
||||
return http.get("/api/wxopen/sendcode", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getRegister(param) { // 手机号进行注册
|
||||
return http.post("/api/wxopen/deregister", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getregister(param) { // 微信授权登录
|
||||
return http.post('/api/wxopen/register', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getWxOpenPhone(param) { // 解密手机号
|
||||
return http.post('/api/wxopen/deuserphone', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getDecryptdata(param) { // 解密用户资料
|
||||
return http.post("/api/wxopen/deuserinfo", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getoutlogin(param) { // 退出登录
|
||||
return http.get("/api/wxopen/outlogin", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
submitadvice(param) { // 意见反馈
|
||||
return http.post("/api/wxopen/submitadvice", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
//
|
||||
getUserInfo(param) { //获取用户信息
|
||||
return http.post("/api/adult/info", param).then(res => {
|
||||
if (res.code == 0) {
|
||||
res.data.name = res.data.nickname
|
||||
// res.data.firstresulttime = res.data.firstresulttime.substring(0, 10)
|
||||
}
|
||||
return res
|
||||
})
|
||||
},
|
||||
getResult(param) { //获取成人测量信息
|
||||
return http.post("/api/adult/measureinfo", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getfirstweight(param) { //修改初始体重
|
||||
return http.post("/api/adult/submitfirstweight", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
setTarget(param) { //设置目标体重
|
||||
return http.post("/api/family/settarget", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getbodylist(param) { //测评列表
|
||||
return http.post("/api/adult/getbodylist", param).then(res => {
|
||||
if (res.code == 0) {
|
||||
let box = res.data
|
||||
let k = 1
|
||||
for (var n = 0; n < box.length; n++) {
|
||||
for (var i = 0; i < box[n].qalist.length; i++) {
|
||||
let info = box[n].qalist[i]
|
||||
box[n].qalist[i] = {
|
||||
Id: info.id,
|
||||
title: info.title,
|
||||
data: [{
|
||||
id: info.id,
|
||||
val: k++,
|
||||
value: info.nonevalue,
|
||||
valId: box[n].id,
|
||||
name: '没有',
|
||||
},
|
||||
{
|
||||
id: info.id,
|
||||
val: k++,
|
||||
value: info.littlevalue,
|
||||
valId: box[n].id,
|
||||
name: '很少',
|
||||
},
|
||||
{
|
||||
id: info.id,
|
||||
val: k++,
|
||||
value: info.somevalue,
|
||||
valId: box[n].id,
|
||||
name: '有时',
|
||||
},
|
||||
{
|
||||
id: info.id,
|
||||
val: k++,
|
||||
value: info.oftenvalue,
|
||||
valId: box[n].id,
|
||||
name: '经常',
|
||||
},
|
||||
{
|
||||
id: info.id,
|
||||
val: k++,
|
||||
value: info.alwaysvalue,
|
||||
valId: box[n].id,
|
||||
name: '总是',
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
res.data = box
|
||||
}
|
||||
return res
|
||||
})
|
||||
},
|
||||
getbodyinfo(param) { //体质测评结果
|
||||
return http.post("/api/adult/getbodyinfo", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getbodyresultinfo(param) { //体质测评计算
|
||||
return http.post("/api/adult/getbodyresultinfo", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
//
|
||||
getFamilyList(param) { // 获取家庭成员列表
|
||||
return http.post('/api/family/getlist', param).then(res => {
|
||||
if (res.data) {
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
res.data[i].familyid = res.data[i].id
|
||||
res.data[i].type = res.data[i].type == 1 ? "成人" : res.data[i].type == 2 ? "儿童" : "婴儿"
|
||||
}
|
||||
}
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
getsubmit(param) { //家庭成员信息修改
|
||||
return http.post('/api/family/submit', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getdelete(param) { //删除家庭成员
|
||||
return http.get('/api/family/delete', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
|
||||
getdetail(param) { //家庭成员详情
|
||||
return http.get('/api/family/detail', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getHistoryList(param) { //获取指定家庭成员历史记录
|
||||
return http.post('/api/family/gethistorylist', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getaddlist(param) { //手动添加记录列表
|
||||
return http.post('/api/family/getaddlist', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
//
|
||||
getinsertmeasure(param) { //手动记录
|
||||
return http.post('/api/result/insertmeasure', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getmeasure(param) { //新增蓝牙测量记录
|
||||
return http.post('/api/result/measure', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getmeasuredata(param) { //新增蓝牙测量记录,适用于f01pro
|
||||
return http.post('/api/result/measuredata', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getmeasurefunit(param) { //新增蓝牙测量记录,身高带单位
|
||||
return http.post('/api/result/measureofunit', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
gethistorydelete(param) { //删除历史记录
|
||||
return http.post("/api/result/delete", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getTrendList(param) { //趋势
|
||||
return http.post("/api/result/trendlist", param).then(res => {
|
||||
if (res.code == 0) {
|
||||
let list = res.data
|
||||
let cidata = {
|
||||
weight: {
|
||||
categories: [],
|
||||
series: [{
|
||||
color: "#ff9f40",
|
||||
name: "体重",
|
||||
data: [],
|
||||
}]
|
||||
},
|
||||
bmi: {
|
||||
categories: [],
|
||||
series: [{
|
||||
name: "bmi",
|
||||
color: "#5ba7ff",
|
||||
data: [],
|
||||
}]
|
||||
},
|
||||
muscle: {
|
||||
categories: [],
|
||||
series: [{
|
||||
color: "#ff7f91",
|
||||
name: "肌肉",
|
||||
data: [],
|
||||
}]
|
||||
},
|
||||
fat_r: {
|
||||
categories: [],
|
||||
series: [{
|
||||
color: "#3fcba7",
|
||||
name: "脂肪",
|
||||
data: [],
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
cidata.weight.categories.push(list[i].time);
|
||||
cidata.bmi.categories.push(list[i].time);
|
||||
cidata.muscle.categories.push(list[i].time);
|
||||
cidata.fat_r.categories.push(list[i].time);
|
||||
cidata.weight.series.forEach(item => {
|
||||
item.data.push(list[i].weight)
|
||||
})
|
||||
cidata.bmi.series.forEach(item => {
|
||||
item.data.push(list[i].bmi)
|
||||
})
|
||||
cidata.muscle.series.forEach(item => {
|
||||
item.data.push(list[i].muscle)
|
||||
})
|
||||
cidata.fat_r.series.forEach(item => {
|
||||
item.data.push(list[i].fat_r)
|
||||
})
|
||||
}
|
||||
res.data = cidata
|
||||
}
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
//对比列表
|
||||
GetTrendList(param) {
|
||||
return http.post("/api/result/trendlist", param).then(res => {
|
||||
if (res.code == 0) {
|
||||
let pkList = {
|
||||
list: [],
|
||||
Dlist: []
|
||||
}
|
||||
for (var i = 0; i < res.data.length; i++) {
|
||||
pkList.list.push(res.data[i])
|
||||
if (!pkList.Dlist.includes(res.data[i].createtime)) { //includes 检测数组是否有某个值
|
||||
pkList.Dlist.push(res.data[i].createtime);
|
||||
}
|
||||
}
|
||||
res.data.pkList = pkList
|
||||
}
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
getresultdiff(param) { //记录对比
|
||||
return http.post("/api/result/resultdiff", param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
|
||||
//
|
||||
getdevactive(param) { //设备激活
|
||||
return http.post('/api/device/active', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getdevstatus(param) { //检查设备状态
|
||||
return http.get('/api/device/checkdevstatus', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
getdevdetail(param) { //设备详情
|
||||
return http.post('/api/device/detail', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
//
|
||||
GetTplList(param) { //获取消息模板列表
|
||||
return http.get('/api/message/gettplList', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
GetSubscribe(param) { //消息订阅
|
||||
return http.post('/api/message/subscribe', param).then(res => {
|
||||
return res
|
||||
|
||||
})
|
||||
},
|
||||
GetSubscribeInfo(param) { //获取订阅状态
|
||||
return http.get('/api/message/getsubscribeinfo', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
Getunsubscribe(param) { //取消订阅
|
||||
return http.post('/api/message/unsubscribe', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
// 协议
|
||||
GetAdListDetail(param) {
|
||||
return http.get('/api/zx/infodetail', param).then(res => {
|
||||
return res
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
import $store from '@/store'
|
||||
export default {
|
||||
msg,
|
||||
str2hex,
|
||||
hex2str,
|
||||
ab2hex,
|
||||
inArray,
|
||||
getAge,
|
||||
getTime,
|
||||
getDate,
|
||||
getMonth,
|
||||
GetDateStr,
|
||||
handlePages,
|
||||
getBluetoothAdapter
|
||||
}
|
||||
|
||||
function inArray(arr, key, val) {
|
||||
if (!arr || !arr.length || typeof arr != 'object' || !Array.isArray(arr)) {
|
||||
return -1
|
||||
}
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (!key) {
|
||||
if (arr[i] == val) {
|
||||
return i
|
||||
}
|
||||
} else if (arr[i][key] === val) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function msg(str) {
|
||||
uni.showToast({
|
||||
title: str,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
function ab2hex(buffer, split) {
|
||||
var hexArr = Array.prototype.map.call(
|
||||
new Uint8Array(buffer),
|
||||
function(bit) {
|
||||
return ('00' + bit.toString(16)).slice(-2)
|
||||
}
|
||||
)
|
||||
return hexArr.join(split);
|
||||
}
|
||||
|
||||
function hex2str(arr) {
|
||||
let decoder = new TextDecoder('utf8')
|
||||
let uint8 = new Uint8Array(arr)
|
||||
let res = decoder.decode(uint8)
|
||||
return res
|
||||
}
|
||||
|
||||
function str2hex(str) {
|
||||
let encoder = new TextEncoder('utf8')
|
||||
return encoder.encode(str)
|
||||
}
|
||||
|
||||
function getBluetoothAdapter(err) {
|
||||
if (err.errMsg == "openBluetoothAdapter:fail auth denied" || err.errMsg ===
|
||||
"openBluetoothAdapter:fail auth deny" ||
|
||||
err.errMsg === "openBluetoothAdapter:fail authorize no response"
|
||||
) {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "需要您授权使用手机蓝牙",
|
||||
showCancel: false,
|
||||
success(modalSuccess) {
|
||||
uni.openSetting({
|
||||
success(settingdata) {
|
||||
if (settingdata.authSetting["scope.bluetooth"]) {
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
uni.showToast({
|
||||
title: "获取权限成功,请继续去测量",
|
||||
icon: "none"
|
||||
})
|
||||
$store.commit("changeBluetooth", true);
|
||||
},
|
||||
fail: err => {
|
||||
uni.showToast({
|
||||
title: "请打开手机蓝牙",
|
||||
icon: "none",
|
||||
duration: 1000,
|
||||
})
|
||||
console.log('初始化蓝牙失败:' + err.errMsg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "获取权限失败,将无法使用手机蓝牙进行测量",
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "请打开手机蓝牙",
|
||||
icon: "none",
|
||||
duration: 1000,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
let day = date.getDate();
|
||||
month = month > 9 ? month : '0' + month;;
|
||||
day = day > 9 ? day : '0' + day;
|
||||
if (type === 'tow') {
|
||||
year = year - 2;
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
if (type === 'start') {
|
||||
year = year;
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
if (type === 'end') {
|
||||
year = year + 60;
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
if (type == "m") {
|
||||
if (month == "01" || month == "03" || month == "05" || month == "07" || month == "08" || month == "10" ||
|
||||
month == "12") {
|
||||
return year + "/" + month + "/01" + "~" + year + "/" + month + "/31";
|
||||
} else if (month == "02") {
|
||||
if ((year % 4 == 0 && year % 100 != 0) || (year % 100 == 0 && year % 400 == 0)) {
|
||||
return year + "/" + month + "/01" + "~" + year + "/" + month + "/29";
|
||||
} else {
|
||||
return year + "/" + month + "/01" + "~" + year + "/" + month + "/28";
|
||||
};
|
||||
} else {
|
||||
return year + "/" + month + "/01" + "~" + year + "/" + month + "/30";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function GetDateStr(AddDayCount) {
|
||||
var dd = new Date();
|
||||
dd.setDate(dd.getDate() + AddDayCount); //获取AddDayCount天后的日期
|
||||
var y = dd.getFullYear();
|
||||
var m = (dd.getMonth() + 1) < 10 ? "0" + (dd.getMonth() + 1) : (dd.getMonth() + 1); //获取当前月份的日期,不足10补0
|
||||
var d = dd.getDate() < 10 ? "0" + dd.getDate() : dd.getDate(); //获取当前几号,不足10补0
|
||||
return y + "-" + m + "-" + d;
|
||||
}
|
||||
|
||||
// 获取当前日期
|
||||
function getTime() {
|
||||
var date = new Date()
|
||||
var todate =
|
||||
((date.getMonth() + 1) < 10 ? ('0' + (date.getMonth() + 1)) : date.getMonth() +
|
||||
1) + '月' + (date.getDate() < 10 ? ('0' + date.getDate()) : date.getDate() + '日')
|
||||
return todate
|
||||
}
|
||||
// 根据出生日期获取年龄
|
||||
function getAge(str) {
|
||||
var r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})/);
|
||||
if (r == null) return false;
|
||||
|
||||
var d = new Date(r[1], r[3] - 1, r[4]);
|
||||
var returnStr = "输入的日期格式错误!";
|
||||
|
||||
if (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4]) {
|
||||
|
||||
var date = new Date();
|
||||
var yearNow = date.getFullYear();
|
||||
var monthNow = date.getMonth() + 1;
|
||||
var dayNow = date.getDate();
|
||||
|
||||
var largeMonths = [1, 3, 5, 7, 8, 10, 12], //大月, 用于计算天,只在年月都为零时,天数有效
|
||||
lastMonth = monthNow - 1 > 0 ? monthNow - 1 : 12, // 上一个月的月份
|
||||
isLeapYear = false, // 是否是闰年
|
||||
daysOFMonth = 0; // 当前日期的上一个月多少天
|
||||
|
||||
if ((yearNow % 4 === 0 && yearNow % 100 !== 0) || yearNow % 400 === 0) { // 是否闰年, 用于计算天,只在年月都为零时,天数有效
|
||||
isLeapYear = true;
|
||||
}
|
||||
|
||||
if (largeMonths.indexOf(lastMonth) > -1) {
|
||||
daysOFMonth = 31;
|
||||
} else if (lastMonth === 2) {
|
||||
if (isLeapYear) {
|
||||
daysOFMonth = 29;
|
||||
} else {
|
||||
daysOFMonth = 28;
|
||||
}
|
||||
} else {
|
||||
daysOFMonth = 30;
|
||||
}
|
||||
|
||||
var Y = yearNow - parseInt(r[1]);
|
||||
var M = monthNow - parseInt(r[3]);
|
||||
var D = dayNow - parseInt(r[4]);
|
||||
if (D < 0) {
|
||||
D = D + daysOFMonth; //借一个月
|
||||
M--;
|
||||
}
|
||||
if (M < 0) { // 借一年 12个月
|
||||
Y--;
|
||||
M = M + 12; //
|
||||
}
|
||||
|
||||
if (Y < 0) {
|
||||
returnStr = "出生日期有误!";
|
||||
|
||||
} else if (Y === 0) {
|
||||
if (M === 0) {
|
||||
returnStr = D + "天";
|
||||
} else {
|
||||
returnStr = M + "个月";
|
||||
}
|
||||
} else {
|
||||
if (M === 0) {
|
||||
returnStr = Y + "岁";
|
||||
} else {
|
||||
returnStr = Y + "岁" + M + "个月";
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnStr;
|
||||
}
|
||||
|
||||
function getMonth(dates, months) {
|
||||
var d = new Date(dates.substring(0, 10));
|
||||
let year = d.getFullYear();
|
||||
var month = d.getMonth() + 1;
|
||||
if (Math.abs(months) > 12) {
|
||||
months = months % 12;
|
||||
};
|
||||
if (months != 0) {
|
||||
if (month + months > 12) {
|
||||
year++;
|
||||
month = (month + months) % 12;
|
||||
} else if (month + months < 1) {
|
||||
year--;
|
||||
month = 12 + month + months;
|
||||
} else {
|
||||
month = month + months;
|
||||
};
|
||||
};
|
||||
month = month < 10 ? "0" + month : month;
|
||||
var date = d.getDate();
|
||||
if (month == "01" || month == "03" || month == "05" || month == "07" || month == "08" || month == "10" ||
|
||||
month == "12") {
|
||||
return year + "/" + month + "/01" + "~" + year + "/" + month + "/31";
|
||||
} else if (month == "02") {
|
||||
if ((year % 4 == 0 && year % 100 != 0) || (year % 100 == 0 && year % 400 == 0)) {
|
||||
return year + '/' + month + "/01" + "~" + year + "/" + year + "/" + month + "/29";
|
||||
} else {
|
||||
return year + '/' + month + "/01" + "~" + year + "/" + month + "/28";
|
||||
};
|
||||
} else {
|
||||
return year + '/' + month + "/01" + "~" + year + "/" + month + "/30";
|
||||
};
|
||||
};
|
||||
// 页面跳转
|
||||
function handlePages(type, deviceId) {
|
||||
if (type == 1) {
|
||||
uni.redirectTo({
|
||||
url: "/BLEPages/adult/PCD01pro?deviceId=" + deviceId
|
||||
})
|
||||
return
|
||||
}
|
||||
if (type == 4) {
|
||||
uni.redirectTo({
|
||||
url: "/BLEPages/adult/PCL01?deviceId=" + deviceId
|
||||
})
|
||||
return
|
||||
}
|
||||
if (type == 8) {
|
||||
uni.redirectTo({
|
||||
url: "/BLEPages/adult/H01pro?deviceId=" + deviceId
|
||||
})
|
||||
return
|
||||
}
|
||||
if (type == 14) {
|
||||
uni.redirectTo({
|
||||
url: "/BLEPages/adult/F01B?deviceId=" + deviceId
|
||||
})
|
||||
return
|
||||
}
|
||||
if (type == 21) {
|
||||
uni.redirectTo({
|
||||
url: "/BLEPages/adult/H09B?deviceId=" + deviceId
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* 这里是uni-app内置的常用样式变量
|
||||
*
|
||||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||
*
|
||||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||
*/
|
||||
|
||||
/* 颜色变量 */
|
||||
|
||||
/* 行为相关颜色 */
|
||||
$uni-color-primary: #007aff;
|
||||
$uni-color-success: #4cd964;
|
||||
$uni-color-warning: #f0ad4e;
|
||||
$uni-color-error: #dd524d;
|
||||
|
||||
/* 文字基本颜色 */
|
||||
$uni-text-color:#333;//基本色
|
||||
$uni-text-color-inverse:#fff;//反色
|
||||
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||
$uni-text-color-placeholder: #808080;
|
||||
$uni-text-color-disable:#c0c0c0;
|
||||
|
||||
/* 背景颜色 */
|
||||
$uni-bg-color:#ffffff;
|
||||
$uni-bg-color-grey:#f8f8f8;
|
||||
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||
|
||||
/* 边框颜色 */
|
||||
$uni-border-color:#c8c7cc;
|
||||
|
||||
/* 尺寸变量 */
|
||||
|
||||
/* 文字尺寸 */
|
||||
$uni-font-size-sm:24rpx;
|
||||
$uni-font-size-base:28rpx;
|
||||
$uni-font-size-lg:32rpx;
|
||||
|
||||
/* 图片尺寸 */
|
||||
$uni-img-size-sm:40rpx;
|
||||
$uni-img-size-base:52rpx;
|
||||
$uni-img-size-lg:80rpx;
|
||||
|
||||
/* Border Radius */
|
||||
$uni-border-radius-sm: 4rpx;
|
||||
$uni-border-radius-base: 6rpx;
|
||||
$uni-border-radius-lg: 12rpx;
|
||||
$uni-border-radius-circle: 50%;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-row-sm: 10px;
|
||||
$uni-spacing-row-base: 20rpx;
|
||||
$uni-spacing-row-lg: 30rpx;
|
||||
|
||||
/* 垂直间距 */
|
||||
$uni-spacing-col-sm: 8rpx;
|
||||
$uni-spacing-col-base: 16rpx;
|
||||
$uni-spacing-col-lg: 24rpx;
|
||||
|
||||
/* 透明度 */
|
||||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||
|
||||
/* 文章场景相关 */
|
||||
$uni-color-title: #2C405A; // 文章标题颜色
|
||||
$uni-font-size-title:40rpx;
|
||||
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||
$uni-font-size-subtitle:36rpx;
|
||||
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||
$uni-font-size-paragraph:30rpx;
|
||||
// 自定义
|
||||
$mainColor:linear-gradient(-180deg,#95E0DB,#75DAD0 80%,);
|
||||
$mainColor:#00c6c6;
|
||||
$btncolor:#FCA82D;
|
||||
$greencolor:#00c6c6
|
||||
|
|
@ -0,0 +1,578 @@
|
|||
/*
|
||||
* uCharts®
|
||||
* 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
|
||||
* Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
|
||||
* Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
* 复制使用请保留本段注释,感谢支持开源!
|
||||
*
|
||||
* uCharts®官方网站
|
||||
* https://www.uCharts.cn
|
||||
*
|
||||
* 开源地址:
|
||||
* https://gitee.com/uCharts/uCharts
|
||||
*
|
||||
* uni-app插件市场地址:
|
||||
* http://ext.dcloud.net.cn/plugin?id=271
|
||||
*
|
||||
*/
|
||||
|
||||
// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性
|
||||
const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
|
||||
|
||||
//事件转换函数,主要用作格式化x轴为时间轴,根据需求自行修改
|
||||
const formatDateTime = (timeStamp, returnType) => {
|
||||
var date = new Date();
|
||||
date.setTime(timeStamp * 1000);
|
||||
var y = date.getFullYear();
|
||||
var m = date.getMonth() + 1;
|
||||
m = m < 10 ? ('0' + m) : m;
|
||||
var d = date.getDate();
|
||||
d = d < 10 ? ('0' + d) : d;
|
||||
var h = date.getHours();
|
||||
h = h < 10 ? ('0' + h) : h;
|
||||
var minute = date.getMinutes();
|
||||
var second = date.getSeconds();
|
||||
minute = minute < 10 ? ('0' + minute) : minute;
|
||||
second = second < 10 ? ('0' + second) : second;
|
||||
if (returnType == 'full') {
|
||||
return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
|
||||
}
|
||||
if (returnType == 'y-m-d') {
|
||||
return y + '-' + m + '-' + d;
|
||||
}
|
||||
if (returnType == 'h:m') {
|
||||
return h + ':' + minute;
|
||||
}
|
||||
if (returnType == 'h:m:s') {
|
||||
return h + ':' + minute + ':' + second;
|
||||
}
|
||||
return [y, m, d, h, minute, second];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
//demotype为自定义图表类型,一般不需要自定义图表类型,只需要改根节点上对应的类型即可
|
||||
"type": ["pie", "ring", "rose", "word", "funnel", "map", "arcbar", "line", "column", "area", "radar", "gauge",
|
||||
"candle", "mix", "tline", "tarea", "scatter", "bubble", "demotype"
|
||||
],
|
||||
"range": ["饼状图", "圆环图", "玫瑰图", "词云图", "漏斗图", "地图", "圆弧进度条", "折线图", "柱状图", "区域图", "雷达图", "仪表盘", "K线图", "混合图",
|
||||
"时间轴折线", "时间轴区域", "散点图", "气泡图", "自定义类型"
|
||||
],
|
||||
//增加自定义图表类型,如果需要categories,请在这里加入您的图表类型,例如最后的"demotype"
|
||||
//自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴(矢量x轴)类图表,没有categories,不需要加入categories
|
||||
"categories": ["line", "column", "area", "radar", "gauge", "candle", "mix", "demotype"],
|
||||
//instance为实例变量承载属性,不要删除
|
||||
"instance": {},
|
||||
//option为opts及eopts承载属性,不要删除
|
||||
"option": {},
|
||||
//下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
|
||||
"formatter": {
|
||||
"yAxisDemo1": function(val) {
|
||||
return val + '元'
|
||||
},
|
||||
"yAxisDemo2": function(val) {
|
||||
return val.toFixed(2)
|
||||
},
|
||||
"xAxisDemo1": function(val) {
|
||||
return val + '年'
|
||||
},
|
||||
"xAxisDemo2": function(val) {
|
||||
return formatDateTime(val, 'h:m')
|
||||
},
|
||||
"seriesDemo1": function(val) {
|
||||
return val + '元'
|
||||
},
|
||||
"tooltipDemo1": function(item, category, index, opts) {
|
||||
if (index == 0) {
|
||||
return '随便用' + item.data + '年'
|
||||
} else {
|
||||
return '其他我没改' + item.data + '天'
|
||||
}
|
||||
},
|
||||
"pieDemo": function(val, index, series) {
|
||||
if (index !== undefined) {
|
||||
return series[index].name + ':' + series[index].data + '元'
|
||||
}
|
||||
},
|
||||
},
|
||||
//这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在opts参数,会将demotype与opts中option合并后渲染图表。
|
||||
"demotype": {
|
||||
//我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置
|
||||
"type": "line",
|
||||
"color": color,
|
||||
"padding": [15, 10, 0, 15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"line": {
|
||||
"type": "curve",
|
||||
"width": 2
|
||||
},
|
||||
}
|
||||
},
|
||||
//下面是自定义配置,请添加项目所需的通用配置
|
||||
"pie": {
|
||||
"type": "pie",
|
||||
"color": color,
|
||||
"padding": [5, 5, 5, 5],
|
||||
"extra": {
|
||||
"pie": {
|
||||
"activeOpacity": 0.5,
|
||||
"activeRadius": 10,
|
||||
"offsetAngle": 0,
|
||||
"labelWidth": 15,
|
||||
"border": true,
|
||||
"borderWidth": 3,
|
||||
"borderColor": "#FFFFFF"
|
||||
},
|
||||
}
|
||||
},
|
||||
"ring": {
|
||||
"type": "ring",
|
||||
"color": color,
|
||||
"padding": [5, 5, 5, 5],
|
||||
"rotate": false,
|
||||
"dataLabel": true,
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "right",
|
||||
"lineHeight": 25,
|
||||
},
|
||||
"title": {
|
||||
"name": "收益率",
|
||||
"fontSize": 15,
|
||||
"color": "#666666"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "70%",
|
||||
"fontSize": 25,
|
||||
"color": "#7cb5ec"
|
||||
},
|
||||
"extra": {
|
||||
"ring": {
|
||||
"ringWidth": 30,
|
||||
"activeOpacity": 0.5,
|
||||
"activeRadius": 10,
|
||||
"offsetAngle": 0,
|
||||
"labelWidth": 15,
|
||||
"border": true,
|
||||
"borderWidth": 3,
|
||||
"borderColor": "#FFFFFF"
|
||||
},
|
||||
},
|
||||
},
|
||||
"rose": {
|
||||
"type": "rose",
|
||||
"color": color,
|
||||
"padding": [5, 5, 5, 5],
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "left",
|
||||
"lineHeight": 25,
|
||||
},
|
||||
"extra": {
|
||||
"rose": {
|
||||
"type": "area",
|
||||
"minRadius": 50,
|
||||
"activeOpacity": 0.5,
|
||||
"activeRadius": 10,
|
||||
"offsetAngle": 0,
|
||||
"labelWidth": 15,
|
||||
"border": false,
|
||||
"borderWidth": 2,
|
||||
"borderColor": "#FFFFFF"
|
||||
},
|
||||
}
|
||||
},
|
||||
"word": {
|
||||
"type": "word",
|
||||
"color": color,
|
||||
"extra": {
|
||||
"word": {
|
||||
"type": "normal",
|
||||
"autoColors": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"funnel": {
|
||||
"type": "funnel",
|
||||
"color": color,
|
||||
"padding": [15, 15, 0, 15],
|
||||
"extra": {
|
||||
"funnel": {
|
||||
"activeOpacity": 0.3,
|
||||
"activeWidth": 10,
|
||||
"border": true,
|
||||
"borderWidth": 2,
|
||||
"borderColor": "#FFFFFF",
|
||||
"fillOpacity": 1,
|
||||
"labelAlign": "right"
|
||||
},
|
||||
}
|
||||
},
|
||||
"map": {
|
||||
"type": "map",
|
||||
"color": color,
|
||||
"padding": [0, 0, 0, 0],
|
||||
"dataLabel": true,
|
||||
"extra": {
|
||||
"map": {
|
||||
"border": true,
|
||||
"borderWidth": 1,
|
||||
"borderColor": "#666666",
|
||||
"fillOpacity": 0.6,
|
||||
"activeBorderColor": "#F04864",
|
||||
"activeFillColor": "#FACC14",
|
||||
"activeFillOpacity": 1
|
||||
},
|
||||
}
|
||||
},
|
||||
"arcbar": {
|
||||
"type": "arcbar",
|
||||
"color": color,
|
||||
"title": {
|
||||
"name": "百分比",
|
||||
"fontSize": 25,
|
||||
"color": "#00FF00"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "默认标题",
|
||||
"fontSize": 15,
|
||||
"color": "#666666"
|
||||
},
|
||||
"extra": {
|
||||
"arcbar": {
|
||||
"type": "default",
|
||||
"width": 12,
|
||||
"backgroundColor": "#E9E9E9",
|
||||
"startAngle": 0.75,
|
||||
"endAngle": 0.25,
|
||||
"gap": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"line": {
|
||||
"type": "line",
|
||||
"color": color,
|
||||
"padding": [15, 10, 0, 15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"line": {
|
||||
"type": "straight",
|
||||
"width": 2
|
||||
},
|
||||
}
|
||||
},
|
||||
"tline": {
|
||||
"type": "line",
|
||||
"color": color,
|
||||
"padding": [15, 10, 0, 15],
|
||||
"xAxis": {
|
||||
"disableGrid": false,
|
||||
"boundaryGap": "justify",
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
"data": [{
|
||||
"min": 0,
|
||||
"max": 80
|
||||
}]
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"line": {
|
||||
"type": "curve",
|
||||
"width": 2
|
||||
},
|
||||
}
|
||||
},
|
||||
"tarea": {
|
||||
"type": "area",
|
||||
"color": color,
|
||||
"padding": [0, 15, 15, 5],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
"boundaryGap": "justify",
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"dashLength": 2,
|
||||
"data": [{
|
||||
"min": 0,
|
||||
"max": 80
|
||||
}]
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"area": {
|
||||
"type": "curve",
|
||||
"opacity": 0.2,
|
||||
"addLine": true,
|
||||
"width": 2,
|
||||
"gradient": true
|
||||
},
|
||||
}
|
||||
},
|
||||
"column": {
|
||||
"type": "column",
|
||||
"color": color,
|
||||
"padding": [15, 15, 0, 5],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"disableGrid": true,
|
||||
"gridColor": '#ffffff',
|
||||
"data": [{
|
||||
"tofix": 1,
|
||||
"min": 0
|
||||
}],
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"column": {
|
||||
"type": "group",
|
||||
"width": 20,
|
||||
"seriesGap": 5,
|
||||
"meterFillColor": "#FFFFFF",
|
||||
"activeBgColor": "#000000",
|
||||
"activeBgOpacity": 0.5,
|
||||
"barBorderCircle": true,
|
||||
"linearType": "opacity",
|
||||
// "customColor": "#ff9f40",
|
||||
"linearOpacity": 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
"area": {
|
||||
"type": "area",
|
||||
"color": color,
|
||||
"padding": [20, 15, 5, 10],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"gridType": "dash",
|
||||
"disableGrid": true,
|
||||
"gridColor": '#ffffff',
|
||||
"data": [{
|
||||
"tofix": 1,
|
||||
"min": 0
|
||||
}],
|
||||
},
|
||||
"legend": {
|
||||
"show": false,
|
||||
},
|
||||
"extra": {
|
||||
"area": {
|
||||
"type": "curve",
|
||||
"opacity": 0.2,
|
||||
"addLine": true,
|
||||
"width": 1,
|
||||
"gradient": true
|
||||
},
|
||||
}
|
||||
},
|
||||
"radar": {
|
||||
"type": "radar",
|
||||
"color": color,
|
||||
"padding": [5, 5, 5, 5],
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "right",
|
||||
"lineHeight": 25,
|
||||
},
|
||||
"extra": {
|
||||
"radar": {
|
||||
"gridType": "radar",
|
||||
"gridColor": "#CCCCCC",
|
||||
"gridCount": 3,
|
||||
"opacity": 0.2,
|
||||
"max": 200
|
||||
},
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"type": "gauge",
|
||||
"color": color,
|
||||
"title": {
|
||||
"name": "66Km/H",
|
||||
"fontSize": 25,
|
||||
"color": "#2fc25b",
|
||||
"offsetY": 50
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "实时速度",
|
||||
"fontSize": 15,
|
||||
"color": "#1890ff",
|
||||
"offsetY": -50
|
||||
},
|
||||
"extra": {
|
||||
"gauge": {
|
||||
"type": "default",
|
||||
"width": 30,
|
||||
"labelColor": "#666666",
|
||||
"startAngle": 0.75,
|
||||
"endAngle": 0.25,
|
||||
"startNumber": 0,
|
||||
"endNumber": 100,
|
||||
"labelFormat": "",
|
||||
"splitLine": {
|
||||
"fixRadius": 0,
|
||||
"splitNumber": 10,
|
||||
"width": 30,
|
||||
"color": "#FFFFFF",
|
||||
"childNumber": 5,
|
||||
"childWidth": 12
|
||||
},
|
||||
"pointer": {
|
||||
"width": 24,
|
||||
"color": "auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"candle": {
|
||||
"type": "candle",
|
||||
"color": color,
|
||||
"padding": [15, 15, 0, 15],
|
||||
"enableScroll": true,
|
||||
"enableMarkLine": true,
|
||||
"dataLabel": false,
|
||||
"xAxis": {
|
||||
"labelCount": 4,
|
||||
"itemCount": 40,
|
||||
"disableGrid": true,
|
||||
"gridColor": "#CCCCCC",
|
||||
"gridType": "solid",
|
||||
"dashLength": 4,
|
||||
"scrollShow": true,
|
||||
"scrollAlign": "left",
|
||||
"scrollColor": "#A6A6A6",
|
||||
"scrollBackgroundColor": "#EFEBEF"
|
||||
},
|
||||
"yAxis": {},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"candle": {
|
||||
"color": {
|
||||
"upLine": "#f04864",
|
||||
"upFill": "#f04864",
|
||||
"downLine": "#2fc25b",
|
||||
"downFill": "#2fc25b"
|
||||
},
|
||||
"average": {
|
||||
"show": true,
|
||||
"name": ["MA5", "MA10", "MA30"],
|
||||
"day": [5, 10, 20],
|
||||
"color": ["#1890ff", "#2fc25b", "#facc14"]
|
||||
}
|
||||
},
|
||||
"markLine": {
|
||||
"type": "dash",
|
||||
"dashLength": 5,
|
||||
"data": [{
|
||||
"value": 2150,
|
||||
"lineColor": "#f04864",
|
||||
"showLabel": true
|
||||
},
|
||||
{
|
||||
"value": 2350,
|
||||
"lineColor": "#f04864",
|
||||
"showLabel": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mix": {
|
||||
"type": "mix",
|
||||
"color": color,
|
||||
"padding": [15, 15, 0, 15],
|
||||
"xAxis": {
|
||||
"disableGrid": true,
|
||||
},
|
||||
"yAxis": {
|
||||
"disabled": false,
|
||||
"disableGrid": false,
|
||||
"splitNumber": 5,
|
||||
"gridType": "dash",
|
||||
"dashLength": 4,
|
||||
"gridColor": "#CCCCCC",
|
||||
"padding": 10,
|
||||
"showTitle": true,
|
||||
"data": []
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"mix": {
|
||||
"column": {
|
||||
"width": 20
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"scatter": {
|
||||
"type": "scatter",
|
||||
"color": color,
|
||||
"padding": [15, 15, 0, 15],
|
||||
"dataLabel": false,
|
||||
"xAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType": "dash",
|
||||
"splitNumber": 5,
|
||||
"boundaryGap": "justify",
|
||||
"min": 0
|
||||
},
|
||||
"yAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType": "dash",
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"scatter": {},
|
||||
}
|
||||
},
|
||||
"bubble": {
|
||||
"type": "bubble",
|
||||
"color": color,
|
||||
"padding": [15, 15, 0, 15],
|
||||
"xAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType": "dash",
|
||||
"splitNumber": 5,
|
||||
"boundaryGap": "justify",
|
||||
"min": 0,
|
||||
"max": 250
|
||||
},
|
||||
"yAxis": {
|
||||
"disableGrid": false,
|
||||
"gridType": "dash",
|
||||
"data": [{
|
||||
"min": 0,
|
||||
"max": 150
|
||||
}]
|
||||
},
|
||||
"legend": {},
|
||||
"extra": {
|
||||
"bubble": {
|
||||
"border": 2,
|
||||
"opacity": 0.5,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||