This commit is contained in:
qiaocl 2025-05-30 11:14:38 +08:00
parent 6250eb4058
commit f380b0e3c8
1368 changed files with 213188 additions and 175 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

22
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,22 @@
{
"version" : "1.0",
"configurations" : [
{
"playground" : "standard",
"type" : "uni-app:app-android"
},
{
"app-plus" : {
"launchtype" : "local"
},
"mp-weixin" : {
"launchtype" : "local"
},
"type" : "uniCloud"
},
{
"playground" : "standard",
"type" : "uni-app:app-ios"
}
]
}

170
App.vue
View File

@ -1,6 +1,42 @@
<script>
let platform = ""
export default {
data() {
return {}
},
onLaunch: function() {
let that = this
// apk
// #ifdef APP-PLUS
uni.getSystemInfo({
success(e) {
platform = e.platform
that.$store.commit('changePhoneInfo', {
platform: e.platform
})
console.log("getSystemInfo", e.platform)
}
})
if (platform === 'ios') { // ios
uni.onNetworkStatusChange(function(res) {
if (res.isConnected == true) {
that.handleCityList()
that.handleCooperationUrl()
uni.reLaunch({
url: '/pageTwo/login/login'
})
console.log("有网络连接", res.isConnected)
}
});
}
that.checkForUpdates()
// #endif
// #ifdef MP-WEIXIN
//
that.handleCityList()
that.handleCooperationUrl()
that.updataWeiXin()
// #endif
console.log('App Launch')
},
onShow: function() {
@ -8,10 +44,140 @@
},
onHide: function() {
console.log('App Hide')
// #ifdef APP-PLUS
uni.offNetworkStatusChange(function(res) {
console.log("取消网络监听")
})
// #endif
},
methods: {
//
checkForUpdates() {
let that = this
plus.runtime.getProperty(plus.runtime.appid, function(info) {
uni.setStorageSync('VERSION', info.version)
that.$store.commit('changePhoneInfo', {
info: info
})
console.log("当前应用版本号", info)
that.handleCityList()
that.handleCooperationUrl()
that.handleoginversion(info)
})
},
//
handleoginversion(info) {
let that = this
that.$model.getloginversion({}).then(res => {
console.log("是否登录及版本号", res)
that.handleCancelUpdate(res.code)
// #ifdef APP-PLUS||APP
let currentVersion = info.version;
let latestVersion = res.data.version
that.$store.commit('changePhoneInfo', {
versionUrl: res.data
})
//
let version = that.$tools.compareVersions(currentVersion, latestVersion)
if (version == -1) { // 01-1
uni.showModal({
title: '发现新版本',
content: '检查到新版本' + res.data.version + ',是否更新?',
success: (modalRes) => {
if (modalRes.confirm) { //
if (platform === 'android') { //
uni.setStorageSync('VERSION', res.data.version)
uni.navigateTo({
url: "/pageTwo/my/about"
})
} else { //ios
plus.runtime.launchApplication({
action: `itms-apps://itunes.apple.com/cn/app/id6654906497?mt=8`
})
}
} else {
that.$tools.msg("稍后可在'关于我们'内更新程序!")
}
}
});
}
// #endif
})
},
//
handleCancelUpdate(code) {
let that = this
if (code == 0) {
uni.reLaunch({
url: "/pages/home/home?type=1"
})
} else {
setTimeout(() => {
uni.reLaunch({
url: '/pageTwo/login/login'
})
}, 500);
}
},
//
handleCityList() {
let that = this
that.$model.getGradeList({}).then((res) => {
// console.log("|", res.data)
if (res.code != 0) return
that.$store.commit('changeCityList', res.data.area_list)
that.$store.commit('changeGradeList', res.data.grade_list)
that.$store.commit('changeIdentityList', res.data.identity_list)
})
},
//
handleCooperationUrl() {
let that = this
that.$model.getCooperationUrl({}).then((res) => {
// console.log("", res.data)
if (res.code != 0) return
this.$store.commit("changeCooperationUrl", res.data);
})
},
//
updataWeiXin() {
let that = this
const updateManager = uni.getUpdateManager()
//
updateManager.onCheckForUpdate(function(res) {
// console.log("", res.hasUpdate)
})
updateManager.onUpdateReady(function() {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function(res) {
if (res.confirm) {
// applyUpdate
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function() {
uni.showModal({
title: '新版本更新失败',
content: '请退出并移除小程序,重新打开...',
})
})
}
}
}
</script>
<style>
<style lang="scss">
/*每个页面公共css */
</style>
/* #ifndef APP-NVUE */
@import "/uni.scss";
@import "/scss/common.scss";
@import "/scss/iconfont.css";
@import "/scss/iconfont-weapp-icon.css";
/* #endif*/
</style>

BIN
Desktop.ini Normal file

Binary file not shown.

24
androidPrivacy.json Normal file
View File

@ -0,0 +1,24 @@
{
"version": "1",
"prompt": "template",
"title": "服务协议和隐私政策",
"message": "  请你务必审慎阅读、充分理解“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"http://tc.pcxbc.com/technology/privacy_index\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "同意并接受",
"buttonRefuse": "暂不同意",
"hrefLoader": "system",
"backToExit": "false",
"second": {
"title": "确认提示",
"message": "  进入应用前,你需先同意<a href=\"http://tc.pcxbc.com/technology/privacy_index\">《隐私政策》</a>,否则将退出应用。",
"buttonAccept": "同意并继续",
"buttonRefuse": "退出应用"
},
"styles": {
"buttonAccept": {
"color": "#327FE8"
},
"buttonRefuse": {
"color": "#666"
},
}
}

74
element/city.vue Normal file
View File

@ -0,0 +1,74 @@
<template>
<view v-if="isCity" class="visible">
<view class="bg" @click="clear"></view>
<view @click.stop class="item">
<view class="groupBtn">
<view @click="visible=false">取消</view>
<view @click="handlesure()" class="sure">确定</view>
</view>
<picker-view @change="bindChange" :value="value" class="picker-view" :indicator-style="indicatorStyle">
<picker-view-column>
<view class="item" v-for="(item,index) in province" :key="index">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in city" :key="index">{{item}}</view>
</picker-view-column>
<!-- <picker-view-column>
<view class="item" v-for="(item,index) in area" :key="index">{{item?item:'请选择'}}</view>
</picker-view-column> -->
</picker-view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
value: [2, 0],
province: [], //
city: [], //
area: [], //
}
},
computed: {
...mapState(["cityList", "user", "isCity"]),
},
mounted() {
let that = this
setTimeout(() => {
that.handleCityList()
console.log("1111", this.user.address, that.cityList, that.province)
}, 500);
},
methods: {
//
handleCityList() {
let that = this
that.province = that.cityList
let str = that.user.address.split(',')[0]
let str2 = that.user.address.split(',')[1]
var Index0 = that.cityList.findIndex((profile) => profile.name === str);
var Index2 = that.cityList[Index0].list.findIndex((ite) => ite === str2);
that.value[0] = Index0
that.value[1] = Index2
that.city = that.cityList[Index0].list
},
}
}
</script>
<style scoped lang="scss">
.bg {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 99;
}
</style>

136
element/drawer.vue Normal file
View File

@ -0,0 +1,136 @@
<template>
<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.head_pic" :src="userinfo.head_pic"></image>
<view class="overflow">{{userinfo.nickname}}</view>
</view>
<view class="drawerList">
<view class="drawerList_item" v-for="(item, index) in List" :key="index" @click="toggle(item)"
v-if="List.length">
<image v-if="item.head_pic" :src="item.head_pic" class="image1"></image>
<view class="right">
<view class="name">
<view class="overflow">
{{item.nickname}}
</view>
<view class="dangqian" v-if="item.id == userinfo.id">当前</view>
</view>
<view class="info">
<view>{{item.gender==1?'男':'女'}}</view>
<view>{{item.age}}</view>
</view>
</view>
</view>
<view class="add" @click="addInfo()">
+
</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('userid', val.id)
uni.setStorageSync('gender', val.gender)
that.$store.dispatch("getUserInfo", {
aud_id: val.id
});
that.$store.dispatch("getResult", {
aud_id: val.id
})
that.$store.commit("changeDrawe", false);
that.handlePublicRecord(val.id)
},
//
handlePublicRecord(id) {
let that = this
that.$model.getPublicRecord({
aud_id: id
}).then(res => {
console.log("公共手动记录", res)
if (res.code == 0) {
that.$store.commit('changePublicRecord', res.data)
}
})
},
//
addInfo() {
let that = this
uni.navigateTo({
url: "/pageTwo/my/userInfo"
})
that.$store.commit("changeDrawe", false);
},
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;
background-color: rgba(0, 0, 0, 0.4);
z-index: 99;
}
}
.headimage {
width: 50px;
height: 50px;
margin: auto;
border-radius: 50%;
margin-bottom: 16rpx;
}
.dangqian {
font-size: 24upx !important;
}
@keyframes wrapper_box {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0%);
}
}
</style>

256
element/headerIndex.vue Normal file
View File

@ -0,0 +1,256 @@
<template>
<view>
<view class="header">
<view class="top" v-if="userList.length">
<view class="headimg" @click="handleAddUser(1)">
<image :src="info.head_pic"></image>
</view>
<view class="info" @click="handleAddUser(1)">
<view class="size18 bold">{{info.nickname}}</view>
<view class="mt-5">
<text class="mr-10">性别{{info.gender==1?'男':info.gender==2?'女':'未知'}}</text>
<text class="ml-10">年龄{{info.age}}</text>
</view>
<view class="mt-5" v-if="info.measure_model==1">当前地区{{info.address}}</view>
</view>
<text class="t-icon t-icon-qiehuan1" @click="$store.commit('changeDrawe', true)" v-if="isLeft"></text>
</view>
<view class="top" v-else @click="handleAddUser(2)">
<view class="info">
暂无成员请先添加~
</view>
<view class="add">
+
</view>
</view>
</view>
<!-- 地区 -->
<view class="cityList">
<view class="area" v-if="isArea" @click="visible = true">
<view>中招地区标准</view>
<view>{{region?region:info.address}}<uni-icons type="bottom"></uni-icons></view>
</view>
<!-- -->
<view v-if="visible" class="visible" @click="visible=false">
<view @click.stop class="item">
<view class="groupBtn">
<view @click="visible=false">取消</view>
<view @click="handlesure()" class="sure">确定</view>
</view>
<picker-view @change="bindChange" :value="value" class="picker-view"
:indicator-style="indicatorStyle">
<picker-view-column>
<view class="item" v-for="(item,index) in province" :key="index">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in city" :key="index">{{item}}</view>
</picker-view-column>
<!-- <picker-view-column>
<view class="item" v-for="(item,index) in area" :key="index">{{item?item:'请选择'}}</view>
</picker-view-column> -->
</picker-view>
</view>
</view>
</view>
<!-- 切换成员 -->
<drawer></drawer>
</view>
</template>
<script>
import {
mapState
} from "vuex";
import drawer from "@/element/drawer.vue"
export default {
name: "headerIndex",
components: {
drawer
},
data() {
return {
value: [2, 0],
visible: false,
region: "",
province: [], //
city: [], //
area: [], //
indicatorStyle: `height: 45px;`,
};
},
computed: {
...mapState(["user", "familayList", "cityList"]),
info() {
return this.user
},
userList() {
return this.familayList
},
userAddress() {
return this.user.address
},
},
props: {
isArea: {
type: Boolean,
default: true
},
isLeft: {
type: Boolean,
default: true
},
},
mounted() {
let that = this
setTimeout(() => {
if (that.isArea) {
that.handleCityList()
}
}, 1000);
},
watch: {
userAddress() {
let that = this
that.region = that.user.address
that.handleCityList()
that.$emit("getAciveCity", that.region)
},
},
methods: {
bindChange: function(e) {
let that = this
if (e.detail.value[0] != that.value[0]) {
e.detail.value[1] = 0
}
that.value = e.detail.value
that.city = that.province[that.value[0]].list
},
handlesure() {
let that = this
let defaultRegion = [that.province[that.value[0]].name, that.city[that.value[1]]]
that.region = defaultRegion.join(",");
that.visible = false
that.$emit("getAciveCity", that.region)
},
//
handleAddUser(ind) {
let that = this
if (uni.getStorageSync('token')) {
let index = that.userList.findIndex((profile) => profile.id == that.info.id)
uni.navigateTo({
url: ind == 1 ? "/pageTwo/my/userInfo?info=" + JSON.stringify(that.userList[index]) :
"/pageTwo/my/userInfo"
})
} else {
console.log("headerIndex跳转登录页面")
uni.reLaunch({
url: '/pageTwo/login/login'
})
}
},
//
handleCityList() {
let that = this
if (that.cityList.length) {
if (that.user.address != '') {
that.province = that.cityList
let str = that.user.address.split(',')[0]
var Index0 = that.province.findIndex((profile) => profile.name == str);
that.value[0] = Index0
console.log("地区", str, Index0)
that.city = that.province[Index0].list
} else {
that.value = [2, 0]
that.city = that.cityList[2].list
}
}
},
}
}
</script>
<style lang="scss" scoped>
.info {
display: flex;
flex-wrap: wrap;
margin-left: 15px;
width: calc(100% - 70px);
view {
width: 100%;
}
last-child {
margin-top: 2px !important;
}
}
.area {
margin: 15px 10px 0;
padding: 15px 10px 10px;
background-color: #fff;
width: calc(100% - 40px);
display: flex;
border-radius: 10px;
justify-content: space-between;
box-shadow: 0px 1px 5px 2px #dfe2e1fc;
}
.item {
line-height: 80rpx;
text-align: center;
}
.visible {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
background-color: rgba(0, 0, 0, 0.6);
.groupBtn {
height: 50px;
line-height: 50px;
background-color: #fff;
display: flex;
justify-content: space-between;
padding: 0 15px;
border-bottom: 1px solid #dfdfdf;
position: absolute;
left: 0;
right: 0;
bottom: 45%;
z-index: 999;
view {
height: 30px;
line-height: 30px;
padding: 0 10px;
background-color: #dfdfdf;
border-radius: 5px;
margin-top: 10px;
}
.sure {
background-color: $textcolor;
color: #fff !important;
}
}
.picker-view {
width: 100%;
height: 45%;
bottom: 0;
position: absolute;
background-color: #fff;
}
}
.t-icon-qiehuan1 {
width: 25px;
height: 25px;
}
</style>

View File

@ -0,0 +1,147 @@
<template>
<view class="wrapper" v-if="isRecord">
<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" :end="endDate" @change="changeLog" :fields="fields">
<view class="uni-input">{{regTime?regTime:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<view class="">
<view class="editem">
<view class="name">第一次</view>
<view class="right">
<input type="digit" v-model="number1" placeholder="请输入">ml
</view>
</view>
<view class="editem">
<view class="name">第二次</view>
<view class="right">
<input type="digit" v-model="number2" placeholder="请输入">ml
</view>
</view>
<view class="editem">
<view class="name">第三次</view>
<view class="right">
<input type="digit" v-model="number3" placeholder="请输入">ml
</view>
</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: "",
number1: '',
number2: "",
number3: "",
fields: "",
}
},
props: {
rtype: null,
},
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.number1) {
that.$tools.msg("请输入第一次吸气值")
return
}
if (!that.number2) {
that.$tools.msg("请输入第二次吸气值")
return
}
if (!that.number3) {
that.$tools.msg("请输入第三次吸气值")
return
}
that.$model.getLungmeasure({
aud_id: uni.getStorageSync('userid'),
time: that.regTime,
one: that.number1,
two: that.number2,
three: that.number3
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.commit("changeRecord", false);
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getLungResult", {
aud_id: uni.getStorageSync('userid')
})
that.regTime = ""
that.number1 = ""
that.number2 = ""
that.number3 = ""
that.onTap()
})
},
//
changeLog(e) {
this.regTime = e.detail.value
},
onTap() {
this.regTime = ""
this.number1 = ""
this.number2 = ""
this.number3 = ""
this.$store.commit("changeRecord", false);
},
hideKeyboard() {
uni.hideKeyboard()
},
}
}
</script>
<style scoped lang="scss">
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.edit {
top: 20%
}
.close {
background: #fff !important;
float: left;
color: #333;
}
</style>

View File

@ -0,0 +1,223 @@
<template>
<view class="wrapper" v-if="isPublicRecord">
<view class="bg" @click="onTap">
<view class="edit" @click.stop>
<view class="title">手动记录</view>
<view class="editem">
<view class="left">项目</view>
<view class="right">
{{labelName}}
</view>
</view>
<!-- -->
<view class="editem">
<view class="left">日期</view>
<view class="right">
<picker mode="date" :end="endDate" @change="changeLog" :fields="fields">
<view class="uni-input">{{regTime?regTime:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<view class="editem" v-if="info&&info.list.length&&listType">
<view class="name">{{describe}}</view>
<view class="right" v-if="listType==4">
<picker mode="multiSelector" :range="timeList" :value="timesTndex" @change="bindTimeChange">
<view class="size16">{{time_m?time_m+':':'请选择'}}{{time_s?time_s:''}}</view>
</picker>
<uni-icons type="bottom" class="ml-10 c666"></uni-icons>
</view>
<view class="right" v-if="listType!=4">
<input :type="listType==1?'number':'digit'" v-model="number" placeholder="请输入">
{{unit}}
</view>
</view>
<view class="editem" v-if="info&&info.time">
<view class="name">时长</view>
<view class="right">
<picker mode="multiSelector" :range="timeList" :value="timesTndex" @change="bindTimeChange">
<view class="size16">{{time_m?time_m+':':'请选择'}}{{time_s?time_s:''}}</view>
</picker>
<uni-icons type="bottom" class="ml-15 c666"></uni-icons>
</view>
</view>
<view class="editem" v-if="info&&info.number">
<view class="name">个数</view>
<view class="right">
<input type="number" v-model="number" placeholder="请输入">
</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 {
name: "",
regTime: "",
number: '',
timeList: [],
time_m: "",
time_s: "",
fields: "",
listType: null,
describe: "",
unit: "",
timesTndex: [1, 0],
lableTndex: 0,
labelName: "",
}
},
props: {
rtype: null,
active: {
type: Number,
default: 0
},
},
computed: {
...mapState(["PublicRecord", "isPublicRecord"]),
info() {
let that = this
let info = {
height: false,
weight: false,
number: false,
time: false,
list: []
}
if (that.PublicRecord.length) {
that.PublicRecord.forEach(ite => {
if (ite.id == that.rtype) {
info = ite
}
})
if (info && info.list.length) {
// console.log("8888888", that.PublicRecord, info, that.active)
that.labelName = info.list[that.active].name
that.listType = info.list[that.active].type
that.describe = info.list[that.active].describe
that.unit = info.list[that.active].unit
// console.log("", info, that.active)
}
}
return that.PublicRecord.length ? info : null
},
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
mounted() {
// console.log("999999", that.labelName, that.PublicRecord)
},
mounted() {
let that = this
that.timeList = this.$tools.gethms()
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
methods: {
bindTimeChange(e) {
let that = this
let m = e.target.value[0]
let s = e.target.value[1]
let time_m = Number(that.timeList[0][m].substring(0, 2)) * 60
let time_s = Number(that.timeList[1][s].substring(0, 2))
that.timesTndex = e.target.value
that.time_m = that.timeList[0][m].substring(0, 2)
that.time_s = that.timeList[1][s].substring(0, 2)
console.log("时长", that.time_m, that.time_s)
},
//
handleTarget() {
let that = this
if (!that.regTime) {
that.$tools.msg("请选择日期")
return
}
if (that.listType == 4 && (!that.time_m || !that.time_s)) {
that.$tools.msg("请输入时长")
return
}
if (that.listType != 4 && !that.number) {
let msg = that.listType == 1 ? '请输入个数' : '请输入时长'
that.$tools.msg(msg)
return
}
let time_m = that.time_m + ':' + that.time_s
that.$model.getpublicmeasure({
acd_id: that.rtype,
name: that.labelName,
record_time: that.regTime,
data: that.listType == 4 ? time_m : that.number,
aud_id: uni.getStorageSync('userid')
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.commit("changeRecord", false);
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid'),
})
that.$store.dispatch("getPublicContent", {
acd_id: that.rtype,
aud_id: uni.getStorageSync('userid')
})
that.onTap()
})
},
bindTimeChange(e) {
let that = this
let m = e.target.value[0]
let s = e.target.value[1]
that.timesTndex = e.target.value
let time_m = Number(that.timeList[0][m].substring(0, 2)) * 60
let time_s = Number(that.timeList[1][s].substring(0, 2))
that.time_m = that.timeList[0][m].substring(0, 2)
that.time_s = that.timeList[1][s].substring(0, 2)
},
//
changeLog(e) {
this.regTime = e.detail.value
},
onTap() {
this.regTime = ""
this.$store.commit("changePublicAdd", false);
},
}
}
</script>
<style scoped lang="scss">
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.edit {
top: 20%
}
.close {
background: #fff !important;
float: left;
color: #333;
}
</style>

View File

@ -0,0 +1,376 @@
<template>
<view class="wrapper" v-if="isRecord">
<view class="bg" @click="onTap">
<view class="edit" @click.stop>
<view class="title">手动记录</view>
<view class="editem">
<view class="left">日期</view>
<view class="right">
<picker mode="date" :end="endDate" @change="changeLog" :fields="fields">
<view class="uni-input">{{regTime?regTime:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<view v-if="rtype!=8&&rtype!=2">
<!-- 项目 -->
<view class="editem" v-if="info&&info.list.length">
<view class="left">项目</view>
<view class="right">
<picker :range="info.list" range-key="name" :value="lableTndex" @change="bindLableChange">
<view class="uni-input">{{name?name:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<!-- 项目时长类型 -->
<view class="editem" v-if="info&&info.list.length&&listType">
<view class="name">{{describe}}</view>
<view class="right" v-if="listType==4">
<picker mode="multiSelector" :range="timeList" :value="timesTndex" @change="bindTimeChange">
<view class="size16">{{time_m?time_m+':':'请选择'}}{{time_s?time_s:''}}</view>
</picker>
<uni-icons type="bottom" class="ml-15 c666"></uni-icons>
</view>
<view class="right" v-if="listType!=4">
<input :type="listType==1?'number':'digit'" v-model="number" placeholder="请输入">
{{unit}}
</view>
</view>
<view class="editem" v-if="info&&info.time">
<view class="name">时长</view>
<view class="right">
<picker mode="multiSelector" :range="timeList" :value="timesTndex" @change="bindTimeChange">
<view class="size16">{{time_m?time_m+':':'请选择'}}{{time_s?time_s:''}}</view>
</picker>
<uni-icons type="bottom" class="ml-15 c666"></uni-icons>
</view>
</view>
<view class="editem" v-if="info&&info.number">
<view class="name">个数</view>
<view class="right">
<input type="number" v-model="number" placeholder="请输入">
</view>
</view>
</view>
<!-- 身体 -->
<view class="" v-if="rtype==2">
<view class="editem" v-if="info&&info.height">
<view class="name">身高</view>
<view class="right">
<input type="digit" v-model="height" placeholder="请输入身高" />cm
</view>
</view>
<view class="editem" v-if="info&&info.weight">
<view class="name">体重</view>
<view class="right">
<input type="digit" v-model="weight" placeholder="请输入体重">kg
</view>
</view>
<view class="editem" v-if="userInfo.stage=='婴儿'">
<view class="left">头围</view>
<view class="right">
<input v-model="head" type="digit" placeholder="请输入" />cm
</view>
</view>
</view>
<!-- 肺活量 -->
<view class="" v-if="rtype==8">
<view class="editem">
<view class="name">第一次</view>
<view class="right">
<input type="digit" v-model="number1" placeholder="请输入">ml
</view>
</view>
<view class="editem">
<view class="name">第二次</view>
<view class="right">
<input type="digit" v-model="number2" placeholder="请输入">ml
</view>
</view>
<view class="editem">
<view class="name">第三次</view>
<view class="right">
<input type="digit" v-model="number3" placeholder="请输入">ml
</view>
</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 {
props: {
rtype: null,
},
data() {
return {
name: "",
number: '',
regTime: "",
number1: '',
number2: "",
number3: "",
time_m: "",
time_s: "",
weight: "",
height: '',
timeList: [],
lableTndex: 0,
timesTndex: [1, 0],
listType: null,
describe: "",
unit: "",
fields: "",
head: ""
}
},
computed: {
...mapState(["user", "isRecord", "PublicRecord", "labelList"]),
userInfo() {
return this.user
},
info() {
let that = this
let info = {
height: false,
weight: false,
number: false,
time: false,
list: []
}
if (that.PublicRecord.length) {
that.PublicRecord.forEach(ite => {
if (ite.id == that.rtype) {
info = ite
}
})
}
return that.PublicRecord.length ? info : null
},
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
mounted() {
let that = this
that.timeList = that.$tools.gethms()
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
methods: {
//
handleTarget() {
let that = this
if (that.rtype == 2) {
that.handleinsertmeasure()
} else if (that.rtype == 6) {
that.handleskipmeasure()
} else if (that.rtype == 8) {
that.handleLungmeasure()
} else {
that.handlepublicmeasure()
}
},
//
handlepublicmeasure() {
let that = this
if (!that.name) {
that.$tools.msg("请选择测量项目")
return
}
if (!that.regTime) {
that.$tools.msg("请选择日期")
return
}
if (that.listType == 4 && (!that.time_m || !that.time_s)) {
that.$tools.msg("请输入时长")
return
}
if (that.listType != 4 && !that.number) {
let msg = that.listType == 1 ? '请输入个数' : '请输入时长'
that.$tools.msg(msg)
return
}
let time_m = that.time_m + ':' + that.time_s
that.$model.getpublicmeasure({
acd_id: that.rtype,
name: that.name,
record_time: that.regTime,
data: that.listType == 4 ? time_m : that.number,
aud_id: uni.getStorageSync('userid')
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid'),
})
that.$store.dispatch("getPublicContent", {
acd_id: that.rtype,
aud_id: uni.getStorageSync('userid')
})
that.onTap()
})
},
//
handleLungmeasure() {
let that = this
if (!that.regTime) {
that.$tools.msg("请选择测量日期")
return
}
if (!that.number1) {
that.$tools.msg("请输入第一次吸气值")
return
}
if (!that.number2) {
that.$tools.msg("请输入第二次吸气值")
return
}
if (!that.number3) {
that.$tools.msg("请输入第三次吸气值")
return
}
that.$model.getLungmeasure({
aud_id: uni.getStorageSync('userid'),
time: that.regTime,
one: that.number1,
two: that.number2,
three: that.number3
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.dispatch("getLungResult", {
aud_id: uni.getStorageSync('userid')
})
that.onTap()
})
},
//
handleskipmeasure() {
let that = this
if (!that.regTime) {
that.$tools.msg("请选择测量日期")
return
}
if (!that.number) {
that.$tools.msg("请输入跳绳个数")
return
}
that.$model.getskipmeasure({
aud_id: uni.getStorageSync('userid'),
num: that.number,
r_time: that.regTime,
time_m: that.time_m,
time_s: that.time_s,
type: "free",
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.dispatch("getSkipResult", {
aud_id: uni.getStorageSync('userid'),
})
that.onTap()
})
},
//
handleinsertmeasure() {
let that = this
if (!that.regTime) {
that.$tools.msg("请选择测量日期")
return
}
if (!that.height) {
that.$tools.msg("请输入测量身高")
return
}
if (!that.weight) {
that.$tools.msg("请输入测量体重")
return
}
that.$model.getinsertmeasure({
aud_id: uni.getStorageSync('userid'),
time: that.regTime,
weight: that.weight,
height: that.height,
head_data: that.head ? that.head : 0
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid')
})
that.onTap()
})
},
bindTimeChange(e) {
let that = this
let m = e.target.value[0]
let s = e.target.value[1]
that.timesTndex = e.target.value
let time_m = Number(that.timeList[0][m].substring(0, 2)) * 60
let time_s = Number(that.timeList[1][s].substring(0, 2))
that.time_m = that.timeList[0][m].substring(0, 2)
that.time_s = that.timeList[1][s].substring(0, 2)
},
bindLableChange(e) {
console.log("e", e)
this.name = this.info.list[e.detail.value].name
this.listType = this.info.list[e.detail.value].type
this.describe = this.info.list[e.detail.value].describe
this.unit = this.info.list[e.detail.value].unit
},
changeLog(e) {
this.regTime = e.detail.value
},
onTap() {
let that = this
that.name = ""
that.weight = ""
that.height = ""
that.regTime = ""
that.number1 = ""
that.number2 = ""
that.number3 = ""
that.number = ''
that.time_m = ""
that.time_s = ""
that.lableTndex = 0
that.timesTndex = [1, 0]
that.listType = null
that.$store.commit("changeRecord", false);
},
}
}
</script>
<style scoped lang="scss">
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.close {
background: #dfdfdf !important;
float: left;
}
</style>

View File

@ -0,0 +1,148 @@
<template>
<view 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" :end="endDate" @change="changeLog" :fields="fields">
<view class="uni-input">{{regTime?regTime:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<view class="">
<view class="editem">
<view class="name">时长</view>
<view class="right">
<picker mode="multiSelector" :range="timeList" :value="timesTndex" @change="bindTimeChange">
<view class="size16">{{time_m?time_m+':':'请选择'}}{{time_s?time_s:''}}</view>
</picker>
<uni-icons type="bottom" class="ml-15 c666"></uni-icons>
</view>
</view>
<view class="editem">
<view class="name">个数</view>
<view class="right">
<input type="number" v-model="number" placeholder="请输入">
</view>
</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: "",
number: '',
timeList: [],
time_m: "",
time_s: "",
timesTndex: [1, 0]
}
},
computed: {
...mapState(["user"]),
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
mounted() {
this.timeList = this.$tools.gethms()
},
methods: {
bindTimeChange(e) {
let that = this
let m = e.target.value[0]
let s = e.target.value[1]
that.timesTndex = e.target.value
let time_m = Number(that.timeList[0][m].substring(0, 2)) * 60
let time_s = Number(that.timeList[1][s].substring(0, 2))
if (Number(time_m + time_s) < 30) {
that.time_m = '00'
that.time_s = '30'
} else {
that.time_m = that.timeList[0][m].substring(0, 2)
that.time_s = that.timeList[1][s].substring(0, 2)
}
},
//
handleTarget() {
let that = this
if (!that.regTime) {
that.$tools.msg("请选择测量日期")
return
}
if (!that.number) {
that.$tools.msg("请输入跳绳个数")
return
}
that.$model.getskipmeasure({
aud_id: uni.getStorageSync('userid'),
r_time: that.regTime,
num: that.number,
time_m: that.time_m,
time_s: that.time_s,
type: "free",
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.commit("changeRecord", false);
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid'),
})
that.$store.dispatch("getSkipResult", {
aud_id: uni.getStorageSync('userid'),
})
that.regTime = ""
that.weight = ""
})
},
//
changeLog(e) {
this.regTime = e.detail.value
},
onTap() {
this.regTime = ""
this.weight = ""
this.$store.commit("changeRecord", false);
},
hideKeyboard() {
uni.hideKeyboard()
},
}
}
</script>
<style scoped lang="scss">
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.edit {
top: 20%
}
.close {
background: #fff !important;
float: left;
color: #333;
}
</style>

View File

@ -0,0 +1,133 @@
<template>
<view class="wrapper wrapperbg">
<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" :end="endDate" @change="changeLog" :fields="fields">
<view class="uni-input">{{regTime?regTime:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<view class="">
<view class="editem">
<view class="name">身高</view>
<view class="right">
<input type="digit" v-model="height" placeholder="请输入身高" />cm
</view>
</view>
<view class="editem">
<view class="name">体重</view>
<view class="right">
<input type="digit" v-model="weight" placeholder="请输入体重">kg
</view>
</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: "",
height: ''
}
},
computed: {
...mapState(["user", "isWeight"]),
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.height) {
that.$tools.msg("请输入测量身高")
return
}
if (!that.weight) {
that.$tools.msg("请输入测量体重")
return
}
that.$store.commit("changeRecord", false);
that.$model.getinsertmeasure({
aud_id: uni.getStorageSync('userid'),
time: that.regTime,
weight: that.weight,
height: that.height,
}).then(res => {
if (res.code != 0) return
that.$tools.msg(res.msg)
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("GetBodyTrendList", {
aud_id: uni.getStorageSync('userid'),
s_time: that.startDate,
e_time: that.endDate
})
that.regTime = ""
that.weight = ""
that.height = ""
})
},
//
changeLog(e) {
this.regTime = e.detail.value
},
onTap() {
this.regTime = ""
this.weight = ""
this.height = ""
this.$store.commit("changeRecord", false);
},
hideKeyboard() {
uni.hideKeyboard()
},
}
}
</script>
<style scoped lang="scss">
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.edit {
top: 20%
}
.close {
background: #fff !important;
float: left;
color: #333;
}
</style>

View File

@ -0,0 +1,434 @@
<template>
<view class="calendar-wrapper">
<view class="header">
<view class="pre" @click="changeMonth('pre')">
<uni-icons type="back" size="26"></uni-icons>
</view>
<view>{{y+'年'+formatNum(m)+'月'}}</view>
<view class="next" @click="changeMonth('next')">
<uni-icons type="forward" size="26"></uni-icons>
</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 (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: 32rpx;
text-align: center;
background-color: #fff;
padding-bottom: 10rpx;
.header {
display: flex;
align-items: center;
justify-content: center;
height: 88rpx;
color: #42464A;
font-size: 36rpx;
font-weight: bold;
justify-content: space-around;
.pre,
.next {
color: $btncolor;
font-size: 32rpx;
}
}
.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>

138
element/slider-fraction.vue Normal file
View File

@ -0,0 +1,138 @@
<template>
<view v-if="isSlider" 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">
<slider @change="sliderChange" value="10" show-value block-size="12" block-color="#007aff">
</slider>
</view>
</view>
<view class="editem">
<view class="left">1分钟跳绳</view>
<view class="right">
<slider @change="sliderChange($event,2)" value="40" show-value block-size="12"
block-color="#007aff"></slider>
</view>
</view>
<view class="editem">
<view class="left">肺活量</view>
<view class="right">
<slider @change="sliderChange" value="60" show-value block-size="12" block-color="#007aff">
</slider>
</view>
</view>
<view class="tips">
*所有项目评分占比和为100%
</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: "",
number1: '',
number2: "",
number3: ""
}
},
computed: {
...mapState(["user", "isSlider"]),
},
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.msg)
that.$store.commit("changeSlider", 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 = ""
})
},
//
sliderChange(event, ind) {
console.log('value 发生变化:', e.detail.value, ind)
},
onTap() {
this.regTime = ""
this.number1 = ""
this.number2 = ""
this.number3 = ""
this.$store.commit("changeSlider", false);
},
}
}
</script>
<style scoped lang="scss">
.edit {
width: 75%;
padding: 15px;
.editem {
padding: 0 !important;
background: #fff !important;
.right {
width: 72% !important;
}
/deep/slider {
width: 100%;
padding: 0 !important;
margin: 0 !important;
}
}
}
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.edit {
top: 20%
}
.close {
background: #dfdfdf !important;
float: left;
}
</style>

View File

@ -0,0 +1,121 @@
<template>
<view v-if="isFirst" class="wrapper wrapperbg">
<view class="bg" @click="onTap">
<view class="edit" @click.stop>
<view class="title">{{type==1?'目标体重':'初始体重'}}</view>
<view class="editem" @click="hideKeyboard" v-if="type!=1">
<view class="name">日期</view>
<view class="right">
<picker mode="date" :end="endDate" @change="changeLog" :fields="fields">
<view class="uni-input">{{regTime?regTime:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</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 {
props: {
type: {}
},
data() {
return {
regTime: "",
weight: "",
fields: "",
}
},
computed: {
...mapState(["user", "isFirst"]),
endDate() {
return this.$tools.getDate("start")
},
},
mounted() {
let that = this
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
methods: {
//
handleTarget() {
let that = this
if (that.type != 1 && !that.regTime) {
that.$tools.msg("请选择测量日期")
return
}
if (!that.weight) {
that.$tools.msg("请输入测量体重")
return
}
that.$model.getfirstweight({
aud_id: that.user.id,
time: that.type == 1 ? '' : that.regTime ? that.regTime : that.user.firstresulttime,
weight: that.weight,
type: that.type
}).then(res => {
console.log("目标,", res)
that.$tools.msg(res.msg)
if (res.code == 0) {
that.$store.commit("changeFirst", false);
that.$store.commit('changeMeasureResult', {
target_current: res.data
})
that.regTime = ""
that.weight = ""
}
})
},
//
changeLog(e) {
this.regTime = e.detail.value
},
onTap() {
this.weight = ""
this.regTime = ""
this.$store.commit("changeFirst", false);
},
hideKeyboard() {
uni.hideKeyboard()
},
}
}
</script>
<style scoped lang="scss">
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.edit {
top: 20%
}
.close {
background: #fff !important;
float: left;
color: #333;
}
</style>

View File

@ -0,0 +1,210 @@
<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.msg)
that.$store.commit("changeTarget", false);
that.$store.dispatch("getUserInfo", {
familyid: that.user.familyid,
})
})
},
onTap() {
this.inputvalue = ""
this.$store.commit("changeTarget", false);
}
}
}
</script>
<style scoped lang="scss">
.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;
background-color: rgba(0, 0, 0, 0.4);
z-index: 99;
}
.edit {
width: 15rem;
height: auto;
background: #fff;
border-radius: 10px;
padding: 15px;
position: relative;
top: 15%;
margin: auto;
z-index: 99999;
overflow: hidden;
.title {
text-align: center;
width: 100%;
color: #333;
font-size: 36rpx;
font-weight: bold;
}
.editem {
position: relative;
display: flex;
font-size: 32rpx;
border-radius: 10px;
margin-top: 15px;
height: 40px;
justify-content: space-between;
background: #eee;
padding: 0px 10px;
align-items: center;
.radioimg {
font-size: 44rpx;
color: $btncolor;
}
.radio {
width: 50%;
text-align: right;
display: flex;
justify-content: center;
align-items: center;
}
.name {
width: 4rem;
color: #333;
}
.right {
width: 60%;
height: 40px;
line-height: 40px;
text-align: right;
display: flex;
justify-content: flex-end;
input {
margin-right: 10px;
height: 40px;
line-height: 40px;
text-align: left;
}
picker {
width: 100%;
text-align: left;
}
.uni-input {
position: absolute;
right: 30px;
top: 0;
left: 0;
height: 40px;
line-height: 40px;
text-align: right;
z-index: 9999;
}
}
.value {
position: relative;
z-index: 999;
width: 3rem;
text-align: center;
float: left;
margin-right: 10px;
}
.iconfont {
margin-left: 10px;
float: right;
display: flex;
}
}
.tips {
font-size:28rpx;
color: #999;
text-align: center;
margin-top: 15px;
margin-bottom: 20px;
display: flex;
}
}
}
.btn {
width: 40%;
float: right;
margin-top: 15px;
background: $maincolor !important;
}
.edit {
top: 20%
}
.close {
background: #dfdfdf !important;
float: left;
}
</style>

View File

@ -1,20 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

34
main.js
View File

@ -1,22 +1,42 @@
import App from './App'
// vuex
import store from './store'
Vue.prototype.$store = store;
// 公共js
import tools from '@/toolJs/tools.js'
Vue.prototype.$tools = tools;
// 蓝牙js
import Bluetooth from '@/toolJs/Bluetooth.js'
Vue.prototype.$Bluetooth = Bluetooth;
//请求
import http from '@/toolJs/https.js'
Vue.prototype.$http = http;
//接口
import model from '@/toolJs/model.js'
Vue.prototype.$model = model;
//模拟数据
import video from '@/video.json'
Vue.prototype.$video = video;
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
import {
createSSRApp
} from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
const app = createSSRApp(App)
return {
app
}
}
// #endif

View File

@ -1,9 +1,9 @@
{
"name" : "ReedawFoodApp",
"appid" : "__UNI__4503CFA",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"name" : "Reedaw",
"appid" : "__UNI__20604F1",
"description" : "面向儿童青少年的健康体质测量APP",
"versionName" : "1.3.4",
"versionCode" : 134,
"transformPx" : false,
/* 5+App */
"app-plus" : {
@ -16,8 +16,14 @@
"autoclose" : true,
"delay" : 0
},
"template" : "index.html",
/* */
"modules" : {},
"modules" : {
"Bluetooth" : {}
},
"compattible" : {
"ignoreVersion" : true // true
},
/* */
"distribute" : {
/* android */
@ -38,21 +44,92 @@
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
],
"abiFilters" : [ "arm64-v8a", "x86" ]
},
/* ios */
"ios" : {},
"ios" : {
"dSYMs" : false,
"idfa" : false,
"privacyDescription" : {
"NSBluetoothAlwaysUsageDescription" : "需要蓝牙权限来连接设备",
"NSBluetoothPeripheralUsageDescription" : "使用蓝牙与外设通信"
}
},
/* SDK */
"sdkConfigs" : {}
"sdkConfigs" : {
"share" : {},
"ad" : {},
"geolocation" : {
"system" : {
"__platform__" : [ "ios" ]
}
}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
},
"splashscreen" : {
"androidStyle" : "common",
"android" : {
"hdpi" : "static/logo.png",
"xhdpi" : "static/logo.png",
"xxhdpi" : "static/logo.png"
},
"useOriginalMsgbox" : true
}
}
},
"permissions" : {
"Android" : [
{
"name" : "android.permission.READ_EXTERNAL_STORAGE",
"desc" : "读取外部存储"
},
{
"name" : "android.permission.WRITE_EXTERNAL_STORAGE",
"desc" : "写入外部存储"
}
]
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"appid" : "wx9c0b7a436ada6d1e",
"setting" : {
"urlCheck" : false
"urlCheck" : false,
"postcss" : true,
"minified" : true
},
"usingComponents" : true
},
@ -66,7 +143,15 @@
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
"enable" : false,
"version" : "2"
},
"vueVersion" : "3"
"vueVersion" : "2",
"locale" : "zh-Hans",
"h5" : {
"template" : "index.html"
},
"fallbackLocale" : "zh-Hans"
}
/* SDK */

585
package-lock.json generated Normal file
View File

@ -0,0 +1,585 @@
{
"name": "examTeamApp",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"vconsole": "^3.15.1",
"vue-i18n": "^9.10.2"
}
},
"node_modules/@babel/parser": {
"version": "7.24.0",
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.0.tgz",
"integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
"peer": true,
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/runtime": {
"version": "7.25.6",
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.25.6.tgz",
"integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@intlify/core-base": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.10.2.tgz",
"integrity": "sha512-HGStVnKobsJL0DoYIyRCGXBH63DMQqEZxDUGrkNI05FuTcruYUtOAxyL3zoAZu/uDGO6mcUvm3VXBaHG2GdZCg==",
"dependencies": {
"@intlify/message-compiler": "9.10.2",
"@intlify/shared": "9.10.2"
},
"engines": {
"node": ">= 16"
}
},
"node_modules/@intlify/message-compiler": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.10.2.tgz",
"integrity": "sha512-ntY/kfBwQRtX5Zh6wL8cSATujPzWW2ZQd1QwKyWwAy5fMqJyyixHMeovN4fmEyCqSu+hFfYOE63nU94evsy4YA==",
"dependencies": {
"@intlify/shared": "9.10.2",
"source-map-js": "^1.0.2"
},
"engines": {
"node": ">= 16"
}
},
"node_modules/@intlify/shared": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.10.2.tgz",
"integrity": "sha512-ttHCAJkRy7R5W2S9RVnN9KYQYPIpV2+GiS79T4EE37nrPyH6/1SrOh3bmdCRC1T3ocL8qCDx7x2lBJ0xaITU7Q==",
"engines": {
"node": ">= 16"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"peer": true
},
"node_modules/@vue/compiler-core": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.23.9",
"@vue/shared": "3.4.21",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.23.9",
"@vue/compiler-core": "3.4.21",
"@vue/compiler-dom": "3.4.21",
"@vue/compiler-ssr": "3.4.21",
"@vue/shared": "3.4.21",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.7",
"postcss": "^8.4.35",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/devtools-api": {
"version": "6.6.1",
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.1.tgz",
"integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA=="
},
"node_modules/@vue/reactivity": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz",
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
"peer": true,
"dependencies": {
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
"peer": true,
"dependencies": {
"@vue/runtime-core": "3.4.21",
"@vue/shared": "3.4.21",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
"peer": true,
"dependencies": {
"@vue/compiler-ssr": "3.4.21",
"@vue/shared": "3.4.21"
},
"peerDependencies": {
"vue": "3.4.21"
}
},
"node_modules/@vue/shared": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.21.tgz",
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
"peer": true
},
"node_modules/copy-text-to-clipboard": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz",
"integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/core-js": {
"version": "3.38.1",
"resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.38.1.tgz",
"integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"peer": true
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"peer": true,
"engines": {
"node": ">=0.12"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"node_modules/magic-string": {
"version": "0.30.8",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.8.tgz",
"integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
"engines": {
"node": ">=12"
}
},
"node_modules/mutation-observer": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/mutation-observer/-/mutation-observer-1.0.3.tgz",
"integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"peer": true
},
"node_modules/postcss": {
"version": "8.4.36",
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.36.tgz",
"integrity": "sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==",
"peer": true,
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.1.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/source-map-js": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.1.0.tgz",
"integrity": "sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/vconsole": {
"version": "3.15.1",
"resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz",
"integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==",
"dependencies": {
"@babel/runtime": "^7.17.2",
"copy-text-to-clipboard": "^3.0.1",
"core-js": "^3.11.0",
"mutation-observer": "^1.0.3"
}
},
"node_modules/vue": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz",
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.4.21",
"@vue/compiler-sfc": "3.4.21",
"@vue/runtime-dom": "3.4.21",
"@vue/server-renderer": "3.4.21",
"@vue/shared": "3.4.21"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/vue-i18n": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.10.2.tgz",
"integrity": "sha512-ECJ8RIFd+3c1d3m1pctQ6ywG5Yj8Efy1oYoAKQ9neRdkLbuKLVeW4gaY5HPkD/9ssf1pOnUrmIFjx2/gkGxmEw==",
"dependencies": {
"@intlify/core-base": "9.10.2",
"@intlify/shared": "9.10.2",
"@vue/devtools-api": "^6.5.0"
},
"engines": {
"node": ">= 16"
},
"peerDependencies": {
"vue": "^3.0.0"
}
}
},
"dependencies": {
"@babel/parser": {
"version": "7.24.0",
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.0.tgz",
"integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
"peer": true
},
"@babel/runtime": {
"version": "7.25.6",
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.25.6.tgz",
"integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
"requires": {
"regenerator-runtime": "^0.14.0"
}
},
"@intlify/core-base": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.10.2.tgz",
"integrity": "sha512-HGStVnKobsJL0DoYIyRCGXBH63DMQqEZxDUGrkNI05FuTcruYUtOAxyL3zoAZu/uDGO6mcUvm3VXBaHG2GdZCg==",
"requires": {
"@intlify/message-compiler": "9.10.2",
"@intlify/shared": "9.10.2"
}
},
"@intlify/message-compiler": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.10.2.tgz",
"integrity": "sha512-ntY/kfBwQRtX5Zh6wL8cSATujPzWW2ZQd1QwKyWwAy5fMqJyyixHMeovN4fmEyCqSu+hFfYOE63nU94evsy4YA==",
"requires": {
"@intlify/shared": "9.10.2",
"source-map-js": "^1.0.2"
}
},
"@intlify/shared": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.10.2.tgz",
"integrity": "sha512-ttHCAJkRy7R5W2S9RVnN9KYQYPIpV2+GiS79T4EE37nrPyH6/1SrOh3bmdCRC1T3ocL8qCDx7x2lBJ0xaITU7Q=="
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"peer": true
},
"@vue/compiler-core": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
"peer": true,
"requires": {
"@babel/parser": "^7.23.9",
"@vue/shared": "3.4.21",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
}
},
"@vue/compiler-dom": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
"peer": true,
"requires": {
"@vue/compiler-core": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"@vue/compiler-sfc": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
"peer": true,
"requires": {
"@babel/parser": "^7.23.9",
"@vue/compiler-core": "3.4.21",
"@vue/compiler-dom": "3.4.21",
"@vue/compiler-ssr": "3.4.21",
"@vue/shared": "3.4.21",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.7",
"postcss": "^8.4.35",
"source-map-js": "^1.0.2"
}
},
"@vue/compiler-ssr": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
"peer": true,
"requires": {
"@vue/compiler-dom": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"@vue/devtools-api": {
"version": "6.6.1",
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.1.tgz",
"integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA=="
},
"@vue/reactivity": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.21.tgz",
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
"peer": true,
"requires": {
"@vue/shared": "3.4.21"
}
},
"@vue/runtime-core": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
"peer": true,
"requires": {
"@vue/reactivity": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"@vue/runtime-dom": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
"peer": true,
"requires": {
"@vue/runtime-core": "3.4.21",
"@vue/shared": "3.4.21",
"csstype": "^3.1.3"
}
},
"@vue/server-renderer": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
"peer": true,
"requires": {
"@vue/compiler-ssr": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"@vue/shared": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.21.tgz",
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
"peer": true
},
"copy-text-to-clipboard": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz",
"integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q=="
},
"core-js": {
"version": "3.38.1",
"resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.38.1.tgz",
"integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw=="
},
"csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"peer": true
},
"entities": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"peer": true
},
"estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"magic-string": {
"version": "0.30.8",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.8.tgz",
"integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"peer": true,
"requires": {
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"mutation-observer": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/mutation-observer/-/mutation-observer-1.0.3.tgz",
"integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
},
"nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"peer": true
},
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"peer": true
},
"postcss": {
"version": "8.4.36",
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.36.tgz",
"integrity": "sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==",
"peer": true,
"requires": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.1.0"
}
},
"regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"source-map-js": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.1.0.tgz",
"integrity": "sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw=="
},
"vconsole": {
"version": "3.15.1",
"resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz",
"integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==",
"requires": {
"@babel/runtime": "^7.17.2",
"copy-text-to-clipboard": "^3.0.1",
"core-js": "^3.11.0",
"mutation-observer": "^1.0.3"
}
},
"vue": {
"version": "3.4.21",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.21.tgz",
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
"peer": true,
"requires": {
"@vue/compiler-dom": "3.4.21",
"@vue/compiler-sfc": "3.4.21",
"@vue/runtime-dom": "3.4.21",
"@vue/server-renderer": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"vue-i18n": {
"version": "9.10.2",
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.10.2.tgz",
"integrity": "sha512-ECJ8RIFd+3c1d3m1pctQ6ywG5Yj8Efy1oYoAKQ9neRdkLbuKLVeW4gaY5HPkD/9ssf1pOnUrmIFjx2/gkGxmEw==",
"requires": {
"@intlify/core-base": "9.10.2",
"@intlify/shared": "9.10.2",
"@vue/devtools-api": "^6.5.0"
}
}
}
}

6
package.json Normal file
View File

@ -0,0 +1,6 @@
{
"dependencies": {
"vconsole": "^3.15.1",
"vue-i18n": "^9.10.2"
}
}

View File

@ -0,0 +1,212 @@
<template>
<view class="TrendPage">
<view class="charts">
<!-- 时间选择 -->
<view class="boxTime">
<view class="one">
<picker mode="date" :end="endDate" @change="handStartTimeH" :fields="fields"
:value="startTime?startTime:startDate">
<view class="uni-input mr-10">{{startTime?startTime:startDate}}
<icon class="iconfont icon-arrow-down-bold"></icon>
</view>
</picker>
<view class="center">~</view>
<picker mode="date" :end="endDate" @change="handEndTimeH" :fields="fields"
:value="endTime?endTime:endDate">
<view class="uni-input mr-10">{{endTime?endTime:endDate}}
<icon class="iconfont icon-arrow-down-bold"></icon>
</view>
</picker>
</view>
</view>
</view>
<!-- 曲线图 -->
<view class="box">
<view class="boxLine">
<view class="line" v-for="(item,index) in weightList">
<view v-if="item.line.categories.length" class="mt-15 mb-15">
<qiunDataCharts type="column" :chartData="item.line" :canvas2d="true" :canvasId="item.id"
:Width="340" :Height="250" :animation="false"
:opts="{enableScroll:true,xAxis:{scrollShow:false,itemCount:3}}" :ontouch="true" />
</view>
<view v-else>
<view class="nolist">
<image src="../../static/none.png"></image>
<text>暂无数据请手动添加~</text>
</view>
<view class="title">
{{item.title}}
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
export default {
components: {
qiunDataCharts,
},
computed: {
...mapState(["labelList"]),
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
data() {
return {
name: "",
list: [],
acd_id: 0,
handTrue: true,
active: 0,
startTime: "",
endTime: "",
fields: "",
weightList: [],
};
},
onLoad(options) {
let that = this
that.active = 0
that.acd_id = options.acd_id
that.time = that.startDate
that.labelList.forEach(ite => {
if (ite.acd_id == that.acd_id) {
that.list = ite.list
that.name = that.list[0]
return
}
})
that.handlePublicTrendList()
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
methods: {
handStartTimeH(e) {
let that = this
if (that.endTime) {
if (Date.parse(e.detail.value) > Date.parse(that.endTime)) {
that.$tools.msg("请选择正确的时间")
return
}
} else {
if (Date.parse(e.detail.value) > Date.parse(that.endDate)) {
that.$tools.msg("请选择正确的时间")
return
}
}
that.startTime = e.detail.value
that.handlePublicTrendList()
},
handEndTimeH(e) {
let that = this
if (that.startTime) {
if (Date.parse(e.detail.value) < Date.parse(that.startTime)) {
that.$tools.msg("请选择正确的时间")
return
}
} else {
if (Date.parse(e.detail.value) < Date.parse(that.startDate)) {
that.$tools.msg("请选择正确的时间")
return
}
}
that.endTime = e.detail.value
that.handlePublicTrendList()
},
handlePublicTrendList() {
let that = this
that.$model.getPublicTrendList({
aud_id: uni.getStorageSync('userid'),
acd_id: that.acd_id,
s_time: that.startTime ? that.startTime : that.startDate,
e_time: that.endTime ? that.endTime : that.endDate
}).then(res => {
// 线
if (res.code == 0) {
that.weightList = res.data
}
console.log("公共曲线", that.weightList)
})
},
navTo(url) {
uni.navigateTo({
url: url
})
}
},
}
</script>
<style lang="scss" scoped>
.TrendPage {
min-height: 100vh;
}
.boxTime {
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
border-radius: 10px 10px 0 0;
.one {
width: 100%;
display: flex;
line-height: 25px;
justify-content: space-between;
align-items: center;
}
.center {
width: 10%;
margin: 0 15px;
}
picker {
width: 50%;
border: none;
display: flex;
justify-content: center;
}
.iconfont {
color: #333333;
font-size: 36rpx;
}
}
.line {
padding-top: 15px;
}
.title {
width: 100%;
text-align: center;
color: #999;
font-size: 14PX;
margin-top: 15px;
text {
width: 15px;
height: 10px;
margin-right: 5px;
display: inline-block;
}
}
</style>

View File

@ -0,0 +1,255 @@
<template>
<view class="content">
<view class="tabbar">
<scroll-view class="scroll-menu" scroll-x="true" style="white-space: nowrap;">
<view v-for="(item,index) in labellist" :class="[active==index?'active':'']"
@click="handleActive(item,index)">
<text>{{item}}</text>
</view>
</scroll-view>
</view>
<view class=" calendar">
<!-- 日历 -->
<ren-calendar ref='ren' :markDays='markDays' @onDayClick='onDayClick' @onMonthClickPre='onMonthClickPre'
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">
<uni-icons :type="isActive.indexOf(item.id)!=-1?'checkbox-filled':'circle'" size="22"
:color="isActive.indexOf(item.id)!=-1?'#FEC407':'#dfdfdf'"></uni-icons>
</view>
<view>{{item.v1}}<text>{{item.v1_name}}</text></view>
<view v-if="item.v2">{{item.v2}}<text>{{item.v2_name}}</text></view>
<view v-if="item.v3">{{item.v3}}<text>{{item.v3_name}}</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.r_t}}</view>
<view>{{ite.v1}}<text>{{ite.v1_name}}</text></view>
<view v-if="ite.v2">{{ite.v2}}<text>{{ite.v2_name}}</text></view>
<view v-if="ite.v3">{{ite.v3}}<text>{{ite.v3_name}}</text></view>
<view class="check">
<uni-icons type="clear" size="22" color="#999"></uni-icons>
</view>
</view>
</view>
<view class="pkclass" v-if="length==2">vs</view>
<!-- <view :class="{'active':length!=2}" class="btn" @click="handlePK">对比</view> -->
</view>
</view>
</view>
</template>
<script>
import RenCalendar from '@/element/ren-calendar/ren-calendar.vue';
import {
mapState
} from "vuex";
export default {
data() {
return {
markDays: [],
infoList: [],
list: [],
isActive: [],
ActiveDays: [],
startM: null,
endM: null,
isShow: true,
acd_id: "",
active: 0,
labelName: "",
}
},
components: {
RenCalendar,
},
computed: {
...mapState(["user", "TrendPk", "labelList"]),
labellist() {
let that = this
let list = []
that.labelList.forEach(ite => {
if (ite.acd_id == that.acd_id) {
list = ite.list
that.labelName = ite.list[0]
}
})
return list
},
length() {
return this.isActive.length
},
endDate() {
return this.$tools.getDate("start")
},
},
onLoad(optoins) {
let that = this
that.acd_id = optoins.acd_id
that.startM = that.$tools.getDate("m").substring(0, 10)
that.endM = that.$tools.getDate("m").substring(11, 21)
that.markDays = []
that.list = []
that.isActive = []
that.ActiveDays = []
that.$nextTick(() => {
that.isShow = true
that.getList(that.startM, that.endM)
})
},
methods: {
getList(start, end) {
let that = this
that.$model.getPublicResultdiff({
aud_id: uni.getStorageSync('userid'),
acd_id: that.acd_id,
s_time: start,
e_time: end,
name: that.labelName
}).then(res => {
if (res) {
that.markDays = res.Dlist
that.list = res.data
for (var i = 0; i < res.data.length; i++) {
if (Date.parse(that.endDate) == Date.parse(res.data[i].r_t)) {
that.infoList.push(res.data[i])
}
}
console.log("对比", res, )
}
})
},
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].r_t)) { //includes
this.infoList.push(that.list[i]);
}
}
},
addMemberTags(index, item) {
var that = this;
console.log("addMemberTags", index, item)
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 (that.isActive.length != 2) {
that.$tools.msg("请先选择数据!")
return
}
let info = {}
info.type = that.acd_id
info.before_id = that.isActive[0]
info.after_id = that.isActive[1]
console.log("1111", info, that.isActive)
uni.navigateTo({
url: "/pageTwo/compk/pkdetail?info=" + JSON.stringify(info)
})
},
handleActive(ite, ind) {
let that = this
that.active = ind
that.labelName = ite
that.startM = that.$tools.getDate("m").substring(0, 10)
that.endM = that.$tools.getDate("m").substring(11, 21)
that.list = []
that.infoList = []
that.markDays = []
that.isActive = []
that.ActiveDays = []
that.$nextTick(() => {
that.isShow = true
that.getList(that.startM, that.endM)
})
},
},
}
</script>
<style scoped lang="scss">
.calendar {
padding-top: 60px;
}
/deep/.calendar-wrapper {
margin: 15px;
.header {
background-color: #fff;
color: $maincolor;
border-radius: 10px 10px 0 0;
}
/deep/uni-icons {
color: $maincolor;
}
}
.item {
font-size: 30rpx !important;
}
.tabbar {
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
justify-content: space-between;
border-bottom: 1px solid #f7f7f7;
box-shadow: 0px 1px 5px 2px #dfe2e1fc;
background-color: #fff;
.scroll-menu {
width: 100%;
white-space: nowrap;
view {
height: 55px;
line-height: 55px;
display: inline-block;
min-width: 100px;
margin: 0 10px;
text-align: center;
}
}
.active {
color: $maincolor;
font-weight: bold;
border-bottom: 2px solid $maincolor;
}
}
</style>

View File

@ -0,0 +1,272 @@
<template>
<view class="common">
<view class="tabbar">
<scroll-view class="scroll-menu" scroll-x="true" style="white-space: nowrap;">
<view v-for="(item,index) in labellist" :class="[active==index?'active':'']"
@click="handleActive(item,index)">
<text>{{item}}</text>
</view>
</scroll-view>
</view>
<view class="history">
<uni-swipe-action>
<uni-swipe-action-item :right-options="item.options" v-for="(item, index) in ranklist" :key="index"
@click="swipeClick($event, index)">
<view class='list'>
<view class="item">
<view class="time">
<icon class="t-icon t-icon-shijian-mianxing-0"></icon>
<text>{{item.record_time}}</text>
</view>
<view>{{item.v1}}<text>{{item.v1_name}}</text></view>
<view>{{item.v2}}<text>{{item.v2_name}}</text></view>
</view>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
<view class="endtext" v-if="!lastPage || page >= lastPage"> 到底了看看别的吧 </view>
</view>
<view class="nolist" v-if="!lastPage">
<image src="../../static/none.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
computed: {
...mapState(['user', 'labelList']),
labellist() {
let that = this
let list = []
that.labelList.forEach(ite => {
if (ite.acd_id == that.acd_id) {
list = ite.list
that.labelName = ite.list[0]
}
})
return list
},
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
data() {
return {
ranklist: [],
page: 1,
isDelete: false,
lastPage: '',
acd_id: "",
active: 0,
labelName: "",
}
},
onLoad(options) {
let that = this
that.acd_id = options.acd_id
that.$nextTick(() => {
that.getList()
})
},
onUnload() {
console.log('关闭页面');
let that = this
var pages = getCurrentPages();
var Page = pages[pages.length - 1]; //
var prevPage = pages[pages.length - 2];
if (that.isDelete) { //
prevPage.$vm.reload()
}
},
onReachBottom() {
let that = this
console.log("onReachBottom", this.lastPage)
if (!this.lastPage || this.page >= this.lastPage) {
uni.showToast({
title: '没有更多数据!',
icon: 'none'
})
return
}
this.page++
this.getList()
},
methods: {
swipeClick(e, index) {
let that = this
let id = that.ranklist[index].id
uni.showModal({
title: '友情提示',
content: '是否删除当前测量记录?',
success: function(res) {
if (res.confirm) {
that.$model.getPublicHistoryDel({
id: id,
}).then((res) => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.ranklist.splice(index, 1)
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid')
})
that.isDelete = true
that.$tools.msg("删除成功")
})
} else if (res.cancel) {
that.$tools.msg("您已取消操作!");
}
},
})
},
getList() {
let that = this
that.$model.getPublicHistory({
aud_id: uni.getStorageSync('userid'),
acd_id: that.acd_id,
page: that.page,
name: that.labelName
}).then((res) => {
console.log("历史记录", res)
if (res.code != 0) return
let options = [{
text: '删除',
style: {
backgroundColor: '#dd524d'
}
}]
res.data.rows.forEach(item => {
item.options = options
})
this.ranklist = this.ranklist.concat(res.data.rows)
this.lastPage = res.data.totalpage
})
},
handleActive(ite, ind) {
let that = this
that.active = ind
that.labelName = ite
that.page = 1
that.ranklist = []
that.lastPage = ""
that.getList()
},
}
}
</script>
<style scoped="scoped" lang="scss">
.common {
width: 100%;
min-height: 100.5vh; //
overflow-y: scroll;
background-color: #f7f7f7;
}
.tabbar {
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
justify-content: space-between;
border-bottom: 1px solid #f7f7f7;
box-shadow: 0px 1px 5px 2px #dfe2e1fc;
background-color: #fff;
.scroll-menu {
width: 100%;
white-space: nowrap;
view {
height: 55px;
line-height: 55px;
display: inline-block;
min-width: 100px;
margin: 0 10px;
text-align: center;
}
}
.active {
color: $maincolor;
font-weight: bold;
border-bottom: 2px solid $maincolor;
}
}
.history {
width: calc(100% - 30px);
height: auto;
margin: 70px 15px 0;
padding-bottom: 40px;
.list {
width: 100%;
margin-top: 12px;
position: relative;
.item {
width: calc(100% - 20px);
height: auto;
background: #fff;
padding: 10px;
display: flex;
justify-content: space-between;
border-radius: 10px;
align-items: center;
font-weight: 700;
font-size: 30rpx !important;
text {
width: 100%;
display: block;
color: #666;
text-align: center;
font-weight: 500;
font-size: 28rpx;
}
view {
width: 28%;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
}
.time {
width: 44% !important;
font-size: 28rpx;
color: #666;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
icon {
width: 40rpx;
height: 40rpx;
margin-right: 5px;
}
text {
width: 100%;
font-size: 30rpx;
margin-top: 3px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
</style>

View File

@ -0,0 +1,156 @@
<template>
<view class="content pkconp">
<view class="headerTop">
<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>性别{{memInfo.gender=='0'?'未知':memInfo.gender=='1'?'男':'女'}}</view>
<view class="ml-15">年龄{{user.age}}</view>
</view>
</view>
</view>
<view class="box" v-if="acd_id==2">
<view class="item">
<view>{{memInfo.day?memInfo.day:'0'}}</view>
<text>时间()</text>
</view>
<view class="item">
<view>{{memInfo.weightdiff?Math.abs(memInfo.weightdiff):0}}</view>
<text v-if="Number(memInfo.weightdiff)>0">增重(kg)</text>
<text v-else>减重(kg)</text>
</view>
<view class="item">
<view>{{memInfo.fat_wdiff?Math.abs(memInfo.fat_wdiff):0}}</view>
<text v-if="Number(memInfo.fat_wdiff)>0">增脂(kg)</text>
<text v-else>减脂(kg)</text>
</view>
<view class="time">
<view>
<uni-icons class="t-icon t-icon-shijian-mianxing-0"></uni-icons>{{memInfo.time}}
</view>数据变化
</view>
</view>
<view class="boxTime" v-else>
<view class=" mt-10 mb-10">
<uni-icons class="t-icon t-icon-shijian-mianxing-0 mr-10 size18"></uni-icons>
{{memInfo.time}}
</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">
<text>{{ite.title}}</text>
</view>
<view class="num">
<text
v-if="ite.diffval!=0||ite.diffval=='0.00'||ite.diffval=='00:00:00'">{{acd_id!=6?Math.abs(ite.diffval):ite.diffval}}</text>
<icon class="t-icon t-icon-shang" v-if="Number(ite.diffval)>0"></icon>
<icon class="t-icon t-icon-xia" v-if="Number(ite.diffval)<0"></icon>
<icon class="t-icon t-icon-hengxian"
v-if="!ite.diffval||ite.diffval=='0.00'||ite.diffval=='00:00:00'"></icon>
</view>
<view class="f">
<view>{{ite.firstresult?ite.firstresult.value:'-'}}</view>
<text>{{ite.firstresult.level}}</text>
</view>
<view class="f">
<view>{{ite.secondresult?ite.secondresult.value:'-'}}</view>
<text>{{ite.secondresult.level}}</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) {
let info = JSON.parse(options.info)
that.acd_id = info.type
that.handleSharepic(JSON.parse(options.info))
}
},
computed: {
...mapState(["user", "appTheme"]),
},
methods: {
handleSharepic(info) {
let that = this
that.$model.getresultcontrast({
type: info.type,
before_id: info.before_id,
after_id: info.after_id,
}).then(res => {
console.log("res", res)
if (res.code != 0) {
this.$tools.msg(res.msg)
return
}
res.data.list.forEach(ite => {
if (ite.firstresult && ite.firstresult.name == 'weight') {
res.data.weightdiff = ite.diffval
}
if (ite.firstresult && ite.firstresult.name == 'fat_w') {
res.data.fat_wdiff = ite.diffval
}
if (ite.firstresult || ite.secondresult) {
ite.name = ite.firstresult ? ite.firstresult.name : ite.secondresult.name
ite.title = ite.firstresult ? ite.firstresult.title : ite.secondresult.title
}
})
that.memInfo = res.data
that.listStr = res.data.list
})
},
},
data() {
return {
memInfo: {},
listStr: [],
acd_id: "",
}
},
}
</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: 2px;
width: 10px;
}
</style>

View File

@ -0,0 +1,75 @@
<template>
<view class="content">
<view class="list">
<view class="item" v-for="(item,index) in list" @click="handlebinging(item)">
<image :src="item.pic"></image>
<view class="name">{{item.name}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: []
}
},
onLoad() {
this.handleUserDeviceList()
},
methods: {
handleUserDeviceList() {
let that = this
that.$model.getDeviceList({}).then(res => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.list = res.data.list
}).catch(err => {})
},
handlebinging(item) {
console.log("item", item)
uni.redirectTo({
url: "/pageTwo/business/search?id=" + item.id
})
}
}
}
</script>
<style scoped lang="scss">
.list {
width: 100%;
.item {
width: 33.3%;
padding-top: 8px;
display: flex;
float: left;
flex-direction: column;
box-sizing: border-box;
justify-content: center;
border-right: 1px solid #dfdfdf;
border-bottom: 1px solid #dfdfdf;
image {
width: 60px;
height: 60px;
margin: 0 auto 10px;
}
.name {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
margin-bottom: 10px;
}
}
}
</style>

View File

@ -0,0 +1,152 @@
<template>
<view class="content">
<view class="add" @click="handleAddDevice()">添加设备</view>
<view class="list">
<view class="item" v-for="(item,index) in list" @click="handleunbind(item,index)">
<view class="left">
<image :src="item.pic"></image>
<view class="name">
<text>{{item.name}}</text>
<text>{{item.bind_time}}</text>
</view>
</view>
<view class="bing">解绑</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
// list: []
}
},
computed: {
...mapState(["user", "userDeviceList"]),
list() {
return this.userDeviceList
}
},
onLoad() {
let that = this
that.$store.dispatch('getUserDeviceList')
},
onPullDownRefresh() {
let that = this
that.$store.dispatch('getUserDeviceList')
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000);
},
methods: {
handleunbind(item, index) {
let that = this
uni.showModal({
title: '友情提示',
content: '是否解绑该设备?',
success: function(res) {
if (res.confirm) {
that.$model.getUnbinding({
id: item.id
}).then(res => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.$tools.msg("操作成功")
that.list.splice(index, 1)
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
})
} else if (res.cancel) {
that.$tools.msg("您已取消操作!");
}
},
})
},
handleAddDevice() {
uni.navigateTo({
url: "/pageTwo/business/addDevice"
})
},
}
}
</script>
<style lang="scss" scoped>
.content {
font-size: 32rpx;
padding: 15px;
background-color: #F5F6FA;
min-height: calc(100vh - 30px);
}
.add {
width: 100%;
height: 35px;
line-height: 35px;
font-size: 32rpx;
margin-bottom: 15px;
color: #fff;
border-radius: 15px;
display: flex;
justify-content: center;
background: $btncolor;
}
.list {
width: 100%;
.item {
width: calc(100% - 20px);
padding: 5px 10px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 10px;
background-color: #fff;
margin-bottom: 10px;
.left {
width: 80%;
display: flex;
align-items: center;
image {
width: 50px;
height: 50px;
margin-right: 10px;
}
.name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
text {
width: 100%;
display: block;
text-align: left;
margin-top: 10px;
}
}
}
.bing {
width: auto;
float: right;
background-color: #dfdfdf;
border-radius: 10px;
padding: 5px 10px;
}
}
}
</style>

297
pageTwo/business/search.vue Normal file
View File

@ -0,0 +1,297 @@
<template>
<view class="container">
<view class="tips">请在设备开机状态下搜索设备</view>
<view class="item" @click="openBluetoothAdapter">开始搜索设备</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.localName ||item.name}}</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>2ios系统需打开设置>应用>微信里的蓝牙权限</text>
<text>3设备亮屏状态下搜索蓝牙</text>
<text>4选择蓝牙进行绑定</text>
</view>
</view>
</view>
</template>
<script>
let that;
let myTime;
import {
mapState
} from "vuex";
export default {
data() {
return {
macAddr: "",
code: "",
deviceId: "",
popup: false,
devices: [],
id: 0
}
},
computed: {
...mapState(["user", "isConnected", "isBluetoothTyle"]),
},
onLoad(options) {
that = this
that.id = options.id
that.$Bluetooth.onBLEConnectionStateChange()
uni.onBluetoothAdapterStateChange(function(res) {
that.$store.commit("changeBluetooth", res.available);
})
console.log("搜索")
},
onUnload() {
console.log("onUnload")
let that = this
if (!that.Unload) {
uni.hideLoading()
that.$Bluetooth.closeBluetoothAdapter() //
that.$Bluetooth.stopBluetoothDevicesDiscovery() //
}
},
methods: {
//
openBluetoothAdapter() {
let that = this
uni.openBluetoothAdapter({
success: e => {
console.log("蓝牙初始化成功")
that.startBluetoothDeviceDiscovery()
},
fail: e => {
console.log('初始化蓝牙失败:' + e.errMsg);
that.$Bluetooth.getBluetoothAdapter(e)
}
});
},
//
startBluetoothDeviceDiscovery() {
let that = this
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true, //
success: res => {
that.onBluetoothDeviceFound();
},
fail: res => {}
});
},
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
const foundDevices = []
wx.showLoading({
title: '设备搜索中',
})
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
if (device.name.indexOf("YPC") != -1) {
clearTimeout(myTime);
let buff = device.name.slice(7, 19)
device.macAddr = that.$Bluetooth.str2Num(buff)
device.deviceId = that.$Bluetooth.str2Num(buff)
that.handleDevice(device)
return
}
if (device.name.indexOf("G02") != -1) {
clearTimeout(myTime);
let buff = device.advertisData.slice(3, 9)
device.mac = new Uint8Array(buff) // 广maciOSmac
let tempMac = Array.from(device.mac)
tempMac.reverse()
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
that.handleDevice(device)
return
}
if (device.name.indexOf("Yihejia_Lung") != -1) {
console.log("肺活量", device, '04:0D:84:48:E0:9B')
device.macAddr = device.deviceId
clearTimeout(myTime);
that.handleDevice(device)
return
}
})
});
that.handleMyTime()
},
handleDevice(device) {
let that = this
const foundDevices = that.devices
const idx = that.$tools.inArray(foundDevices, "deviceId", device.deviceId)
that.deviceId = device.deviceId;
if (idx === -1) {
that.devices.push(device);
} else {
that.devices[idx] = device
}
that.popup = true
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.devices.length) {
that.islink = -1
that.$tools.showModal("没有查找到设备")
}
uni.hideLoading()
clearTimeout(myTime);
that.$Bluetooth.stopBluetoothDevicesDiscovery() //
}, 15000);
},
//
createBLEConnection(e) {
let that = this;
that.$Bluetooth.stopBluetoothDevicesDiscovery()
that.macAddr = e.macAddr
uni.showModal({
title: '提示',
content: '是否绑定该设备?',
cancelText: "取消",
confirmText: "确定",
success: (res) => {
if (res.confirm) {
that.getActive()
} else {
that.$tools.msg("您已取消操作")
}
}
})
},
getActive() {
let that = this
that.$model.getBinding({
device_id: that.id,
device_mac: that.macAddr
}).then(res => {
that.$Bluetooth.closeBluetoothAdapter()
that.devices = []
if (res.code == 0) {
that.$tools.msg('绑定成功!')
that.$store.dispatch('getUserDeviceList')
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
setTimeout(function() {
uni.switchTab({
url: "/pages/home/home"
})
}, 500)
} else {
that.$tools.msg(res.msg)
}
})
},
}
}
</script>
<style scoped lang="scss">
.content {
min-height: calc(100vh - 66px);
padding: 0;
border-top: 66px solid #F9FAFC;
background-color: #fff;
}
.tishi {
width: 100%;
font-size: 28rpx;
line-height: 25px;
font-weight: bold;
position: absolute;
bottom: 20px;
padding-left: 15px;
.text {
display: flex;
align-items: center;
icon {
margin-right: 5px;
}
}
text {
font-weight: 500;
font-size: 32rpx;
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: 36rpx;
color: #666;
}
.device_list {
flex: 1;
width: 100%;
height: auto;
max-height: 340px;
margin-top: 0;
margin-bottom: 10px;
position: absolute;
bottom: 160px;
top: 170px;
.device_item {
font-size: 32rpx;
padding: 7px 10px;
color: #999;
border-bottom: 1px solid #dfdfdf;
text {
display: inline-block;
font-size: 28rpx;
font-weight: bold;
color: #666;
margin-bottom: 5px;
}
}
}
.tips {
font-size: 28rpx;
text-align: center;
color: #e83a1e;
background: #f7e4c8;
padding: 5px 0;
margin-top: 15px;
}
</style>

178
pageTwo/cardList/card.vue Normal file
View File

@ -0,0 +1,178 @@
<template>
<view class="content">
<!-- 已添加的卡片 -->
<view class="box">
<!-- <view class="tips">长按拖拽可调整卡片位置</view> -->
<view class="list">
<view class="item" v-for="(item,index) in cardList.user" @click="deleteCard(item,index)">
<uni-icons type="minus-filled" size="18" color="#FF6D66" v-if="item.id!=2"></uni-icons>
<view class="info">
<image :src="item.pic"></image>
<view>{{item.name}}</view>
</view>
</view>
</view>
</view>
<!-- 可添加的卡片 -->
<view class="box">
<view class="tips2 tips">可添加的卡片</view>
<view class="list">
<view class="item" v-for="(item,index) in cardList.all" @click="addCard(item,index)">
<uni-icons type="plus-filled" size="18" color="#05BD79"></uni-icons>
<view class="info">
<image :src="item.pic"></image>
<view>{{item.name}}</view>
</view>
</view>
</view>
</view>
<view class="btn" @click="handleGradeList()">保存卡片</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
cardList: {
user: [],
all: []
},
}
},
onLoad() {
let that = this
that.handleCardList()
},
computed: {
...mapState(['user']),
},
methods: {
//
handleCardList() {
let that = this
that.$model.getCardAllList({
aud_id: that.user.id
}).then(res => {
console.log("卡片列表", res.data)
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.cardList = res.data
})
},
handleGradeList() {
let that = this
let list = []
that.cardList.user.forEach(ite => {
list.push(ite.id)
})
that.$model.getCardAllOrder({
aud_id: that.user.id,
card_order: list.join(",")
}).then(res => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.$store.dispatch('getUserInfo', {
aud_id: that.user.id
})
uni.switchTab({
url: "/pages/home/home"
})
}).catch(err => {})
},
//
deleteCard(item, index) {
let that = this
if (item.id == 2) return
that.cardList.user.splice(index, 1)
that.cardList.all.push(item)
// that.handleGradeList()
},
//
addCard(item, index) {
let that = this
that.cardList.all.splice(index, 1)
that.cardList.user.push(item)
// that.handleGradeList()
},
}
}
</script>
<style scoped lang="scss">
.content {
padding: 15px;
font-size: 32rpx;
background-color: #F5F6FA;
min-height: 100vh;
.tips {
font-size: 32rpx;
color: #999;
width: 100%;
margin-bottom: 15px;
}
.tips2 {
color: #333;
font-size: 32rpx;
font-weight: bold;
}
.list {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.item {
width: 45%;
background-color: #fff;
margin-bottom: 15px;
position: relative;
height: 60px;
line-height: 60px;
border-radius: 5px;
.uni-icons,
uni-icons {
font-size: 36rpx;
position: absolute;
top: -28px;
left: -5px;
}
.info {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
image {
width: 30px;
height: 30px;
background-color: #F2F2F2;
margin-right: 10px;
border-radius: 50%;
}
}
}
}
}
.btn {
width: auto;
margin: 40px 15px 0;
background: $btncolor !important;
}
</style>

165
pageTwo/compk/contrast.vue Normal file
View File

@ -0,0 +1,165 @@
<template>
<view class="content">
<view class=" calendar">
<!-- 日历 -->
<ren-calendar ref='ren' :markDays='markDays' @onDayClick='onDayClick' @onMonthClickPre='onMonthClickPre'
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">
<uni-icons :type="isActive.indexOf(item.id)!=-1?'checkbox-filled':'circle'" size="22"
:color="isActive.indexOf(item.id)!=-1?'#FEC407':'#dfdfdf'"></uni-icons>
</view>
<view>{{item.v1}}<text>{{item.v1_name}}</text></view>
<view v-if="item.v2">{{item.v2}}<text>{{item.v2_name}}</text></view>
<view v-if="item.v3">{{item.v3}}<text>{{item.v3_name}}</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.r_t}}</view>
<view>{{ite.v1}}<text>{{ite.v1_name}}</text></view>
<view v-if="ite.v2">{{ite.v2}}<text>{{ite.v2_name}}</text></view>
<view v-if="ite.v3">{{ite.v3}}<text>{{ite.v3_name}}</text></view>
<view class="check">
<uni-icons type="clear" size="22" color="#999"></uni-icons>
</view>
</view>
</view>
<view class="pkclass" v-if="length==2">vs</view>
<view :class="{'active':length!=2}" class="btn" @click="handlePK">对比</view>
</view>
</view>
</view>
</template>
<script>
import RenCalendar from '@/element/ren-calendar/ren-calendar.vue';
import {
mapState
} from "vuex";
export default {
data() {
return {
markDays: [],
infoList: [],
list: [],
isActive: [],
ActiveDays: [],
startM: null,
endM: null,
isShow: true,
acd_id: ""
}
},
components: {
RenCalendar,
},
computed: {
...mapState(["user", "TrendPk", "appTheme"]),
length() {
return this.isActive.length
},
endDate() {
return this.$tools.getDate("start")
},
},
onLoad(optoins) {
let that = this
that.acd_id = optoins.acd_id
that.startM = that.$tools.getDate("m").substring(0, 10)
that.endM = that.$tools.getDate("m").substring(11, 21)
that.markDays = []
that.list = []
that.isActive = []
that.ActiveDays = []
this.$nextTick(() => {
that.isShow = true
that.getList(that.startM, that.endM)
})
},
methods: {
getList(start, end) {
let that = this
that.$model.getresultdiff({
aud_id: uni.getStorageSync('userid'),
s_time: start,
e_time: end,
type: that.acd_id
}).then(res => {
if (res) {
that.markDays = res.Dlist
that.list = res.data
for (var i = 0; i < res.data.length; i++) {
if (Date.parse(that.endDate) == Date.parse(res.data[i].r_t)) {
that.infoList.push(res.data[i])
}
}
console.log("对比", res,)
}
})
},
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].r_t)) { //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 (that.isActive.length != 2) {
that.$tools.msg("请先选择数据!")
return
}
let info = {}
info.type = that.acd_id
info.before_id = that.isActive[0]
info.after_id = that.isActive[1]
console.log("1111", info, that.isActive)
uni.navigateTo({
url: "/pageTwo/compk/pkdetail?info=" + JSON.stringify(info)
})
},
},
}
</script>
<style scoped lang="scss">
</style>

156
pageTwo/compk/pkdetail.vue Normal file
View File

@ -0,0 +1,156 @@
<template>
<view class="content pkconp">
<view class="headerTop">
<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>性别{{memInfo.gender=='0'?'未知':memInfo.gender=='1'?'男':'女'}}</view>
<view class="ml-15">年龄{{user.age}}</view>
</view>
</view>
</view>
<view class="box" v-if="acd_id==2">
<view class="item">
<view>{{memInfo.day?memInfo.day:'0'}}</view>
<text>时间()</text>
</view>
<view class="item">
<view>{{memInfo.weightdiff?Math.abs(memInfo.weightdiff):0}}</view>
<text v-if="Number(memInfo.weightdiff)>0">增重(kg)</text>
<text v-else>减重(kg)</text>
</view>
<view class="item">
<view>{{memInfo.fat_wdiff?Math.abs(memInfo.fat_wdiff):0}}</view>
<text v-if="Number(memInfo.fat_wdiff)>0">增脂(kg)</text>
<text v-else>减脂(kg)</text>
</view>
<view class="time">
<view>
<uni-icons class="t-icon t-icon-shijian-mianxing-0"></uni-icons>{{memInfo.time}}
</view>数据变化
</view>
</view>
<view class="boxTime" v-else>
<view class=" mt-10 mb-10">
<uni-icons class="t-icon t-icon-shijian-mianxing-0 mr-10 size18"></uni-icons>
{{memInfo.time}}
</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">
<text>{{ite.title}}</text>
</view>
<view class="num">
<text
v-if="ite.diffval!=0||ite.diffval=='0.00'||ite.diffval=='00:00:00'">{{acd_id!=6?Math.abs(ite.diffval):ite.diffval}}</text>
<icon class="t-icon t-icon-shang" v-if="Number(ite.diffval)>0"></icon>
<icon class="t-icon t-icon-xia" v-if="Number(ite.diffval)<0"></icon>
<icon class="t-icon t-icon-hengxian"
v-if="!ite.diffval||ite.diffval=='0.00'||ite.diffval=='00:00:00'"></icon>
</view>
<view class="f">
<view>{{ite.firstresult?ite.firstresult.value:'-'}}</view>
<text>{{ite.firstresult.level}}</text>
</view>
<view class="f">
<view>{{ite.secondresult?ite.secondresult.value:'-'}}</view>
<text>{{ite.secondresult.level}}</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) {
let info = JSON.parse(options.info)
that.acd_id = info.type
that.handleSharepic(JSON.parse(options.info))
}
},
computed: {
...mapState(["user", "appTheme"]),
},
methods: {
handleSharepic(info) {
let that = this
that.$model.getresultcontrast({
type: info.type,
before_id: info.before_id,
after_id: info.after_id,
}).then(res => {
console.log("res", res)
if (res.code != 0) {
this.$tools.msg(res.msg)
return
}
res.data.list.forEach(ite => {
if (ite.firstresult && ite.firstresult.name == 'weight') {
res.data.weightdiff = ite.diffval
}
if (ite.firstresult && ite.firstresult.name == 'fat_w') {
res.data.fat_wdiff = ite.diffval
}
if (ite.firstresult || ite.secondresult) {
ite.name = ite.firstresult ? ite.firstresult.name : ite.secondresult.name
ite.title = ite.firstresult ? ite.firstresult.title : ite.secondresult.title
}
})
that.memInfo = res.data
that.listStr = res.data.list
})
},
},
data() {
return {
memInfo: {},
listStr: [],
acd_id: "",
}
},
}
</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: 2px;
width: 10px;
}
</style>

527
pageTwo/devices/B20.vue Normal file
View File

@ -0,0 +1,527 @@
<template>
<view class="weightPages">
<view class="content ">
<view class="status">{{textLink}}</view>
<view class="quan">
<view>
<text class="weight">{{weight?weight:'0.00'}}</text>{{unit}}
</view>
<view class="typeInfo" v-if="typeInfo!=0">{{typeInfo==2?'稳定重量':'实时重量'}}</view>
</view>
<view class="btnGroup" v-if="isSave">
<view :class="[IsLing?'disabled':'btnClose']" @click="handleIsLing">清零</view>
<view class="baocun" @click="handleIsNum">锁定</view>
</view>
<view class="tips">
<text>提示</text>
<text>1.请确定设备是开机状态</text>
<text>2.请确定手机蓝牙位置信息已打开</text>
</view>
</view>
<!-- 手动记录 -->
<view class="wrapper" v-if="isHeight">
<view class="bg"></view>
<view class="Blue">
<view class="h4">测量结果提示</view>
<view class="Blue-box">
本次测量体重是<text>{{weight}}{{unit}}</text>
</view>
<view class="Blue-box">
上次测量身高是<input v-model="height" type="digit" placeholder="请输入身高" />cm
</view>
<view class="Blue-box" v-if="userInfo.stage=='婴儿'">
上次测量头围是<input v-model="head" type="digit" placeholder="请输入头围" />cm
</view>
<view class="Blue-btn Blue-close" @click="handleBack">重新测量</view>
<view class="Blue-btn" @click="handleGetMeasure">保存结果</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
export default {
data() {
return {
text: "",
typeInfo: 0,
head: "",
weight: "",
height: "",
unit: "kg",
Unload: false,
isHeight: false,
isSave: true, //
deviceId: "",
serviceId: "",
write: "",
notify: "",
islink: 0, //01-1
textLink: "",
isFinished: false, //
devicesList: [],
IsLing: false, //
IsNum: false, //
}
},
computed: {
...mapState(["user", "isConnected", "isBluetoothTyle"]),
userInfo() {
return this.user
}
},
onUnload: function() {
let that = this
if (!that.Unload) {
clearTimeout(myTime)
that.closeBLEConnection()
that.closeBluetoothAdapter()
console.log("页面返回onUnload")
}
},
onLoad(options) {
let that = this
that.typeInfo = 0
that.height = that.userInfo.height
that.head = that.userInfo.head_data
that.deviceId = options.deviceId
that.createBLEConnection()
that.$Bluetooth.onBLEConnectionStateChange()
uni.onBluetoothAdapterStateChange(function(res) {
that.$store.commit("changeBluetooth", res.available);
})
},
watch: {
isConnected: function() {
let that = this
if (!that.isConnected) {
let text = '测量过程中已与设备连接中断,请重新连接设备再开始测量'
that.$tools.showModal(text)
}
},
isBluetoothTyle: function() {
let that = this
if (!that.isBluetoothTyle) {
let text = '蓝牙已关闭,请重新打开蓝牙后再开始测量'
that.$tools.showModal(text)
}
},
isFinished: function() {
let that = this
console.log("是否开启弹框", that.weight, that.isFinished, that.typeInfo)
if (!that.isFinished) {
that.isHeight = false
return
}
if (that.isFinished && that.typeInfo == 2) {
setTimeout(function() {
that.isHeight = true
}, 1500)
}
}
},
methods: {
//
createBLEConnection() {
let that = this;
uni.createBLEConnection({
deviceId: that.deviceId,
success: res => {
that.textLink = "蓝牙连接中"
setTimeout(function() {
that.getBLEDeviceServices()
}, 1000)
},
fail: res => {
that.textLink = "设备连接失败,返回首页重新连接"
console.log("设备连接失败,请重新连接", res, that.deviceId);
}
});
},
/**
* 获取设备的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("FFF0") != -1) {
that.serviceId = service.uuid;
that.getBLEDeviceCharacteristics();
console.log("设备的FFF0的serviceId " + that.serviceId);
break;
}
}
},
fail: res => {
that.textLink = "设备连接失败,返回首页重新连接"
console.log('获取设备的UUID失败:', res)
}
});
},
/**
* 获取指定服务的特征值
*/
getBLEDeviceCharacteristics() {
let that = this;
uni.getBLEDeviceCharacteristics({
deviceId: that.deviceId,
serviceId: that.serviceId,
success: res => {
// * read: true, //,write: true, //,notify: true
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
if (item.uuid.indexOf('0000FFF1') != -1) {
that.notify = item.uuid
} else if (item.uuid.indexOf('0000FFF2') != -1) {
that.write = item.uuid
that.writeBLECharacteristicValue("A6020500076A") //
}
}
that.textLink = "蓝牙连接成功,请开始测量"
uni.notifyBLECharacteristicValueChange({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.notify,
state: true,
})
uni.notifyBLECharacteristicValueChange({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.write,
state: true,
})
that.isFinished = false
setTimeout(function() {
that.notifyBLECharacteristicValue()
}, 800)
},
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.notify,
success(res) {
that.isSave = true
uni.onBLECharacteristicValueChange(function(res) {
let value = that.$tools.ab2hex(res.value, "");
let type = value.substring(4, 6) //
let typeInfo = value.substring(6, 8) //
let weight = parseInt(value.substring(8, 14), 16) //
let digit = value.substring(18, 19) //
let unit = value.substring(19, 20) //
let weight1 = ""
let weight2 = ""
//
if (digit == "0") {
weight = weight
}
if (digit == "1") {
weight = weight / 10
}
if (digit == '2') {
weight = weight / 100
}
if (digit == "3") {
weight = weight / 1000
}
//
if (unit == "0") {
that.unit = "kg"
}
if (unit == "1") {
that.unit = "斤"
}
if (unit == "2") {
console.log("st:lb", weight)
weight1 = Math.floor(weight / 14)
weight2 = weight - weight1 * 14
weight = weight1 + ":" + weight2.toFixed(2)
that.unit = "st:lb"
}
if (unit == "3") {
that.unit = "lb"
}
if (unit == "4") {
that.unit = "g"
}
//
if (typeInfo == "01") {
that.typeInfo = 1
that.weight = weight
that.IsLing = false
that.isHeight = false
that.isFinished = false
}
//
if (typeInfo == "02" && !that.isFinished) {
that.typeInfo = 2
that.weight = weight
if (weight > 0 || toString(weight) != '0:0.00') {
that.isFinished = true
}
}
console.log("状态:", value, type, typeInfo, weight, that.unit, that.isFinished)
});
},
fail(res) {
console.log("测量失败", res.value);
}
});
},
//
handleIsLing() {
let that = this
if (!that.IsLing) {
that.writeBLECharacteristicValue("A6020500076A")
that.IsLing = true
}
},
//
handleIsNum() {
let that = this
that.writeBLECharacteristicValue("A6020400066A")
},
writeBLECharacteristicValue(str) {
var that = this;
let buf = new Uint8Array(str.match(/[\da-f]{2}/gi).map(function(h) {
return parseInt(h, 16)
}))
console.log("buffer", str, buf)
uni.writeBLECharacteristicValue({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.write,
value: buf.buffer,
success: res => {
console.log('下发指令成功', res.errMsg)
},
fail: res => {
console.log("下发指令失败", res);
},
})
},
//
handleGetMeasure() {
let that = this
if (!that.height) {
this.$tools.msg("请输入身高")
return
}
that.$model.getmeasurefunit({
adc: 0,
weight: that.weight + that.unit,
height: that.height,
aud_id: that.userInfo.id,
head_data: that.head ? that.head : 0
}).then(res => {
that.isHeight = false
that.isSave = false
if (res.code == 0) {
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
that.$tools.msg("测量成功")
} else {
that.$tools.msg("测量失败")
}
that.Unload = true
uni.switchTab({
url: "/pages/home/home"
})
setTimeout(function() {
that.closeBLEConnection()
that.closeBluetoothAdapter()
}, 200)
})
},
//
handleBack() {
let that = this
let str = "A6020500076A"
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.write,
value: buf.buffer,
success: res => {
console.log('下发指令成功', res.errMsg)
uni.showToast({
title: '数据重置中',
icon: "none"
})
console.log("重置", that.typeInfo, that.weight)
// setTimeout(function() {
// that.isHeight = false
// that.isFinished = false
// uni.hideLoading()
// }, 1200)
},
fail: res => {
console.log("下发指令失败", res);
},
})
},
/**
* 停止搜索蓝牙设备
*/
stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success: e => {
console.log("停止搜索蓝牙设备", e)
},
});
},
//
onBLEConnectionStateChange() {
let that = this
uni.onBLEConnectionStateChange(function(res) {
console.log("监听蓝牙连接状态", res.connected)
that.$store.commit("changeConnected", res.connected);
})
},
/**
* 断开蓝牙模块
*/
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: res => {
console.log('蓝牙模块关闭成功');
}
})
},
/**
* 断开蓝牙连接
*/
closeBLEConnection() {
var that = this;
uni.closeBLEConnection({
deviceId: that.deviceId,
success: res => {
console.log('断开蓝牙连接成功');
that.$store.commit("changeConnected", false);
}
});
},
},
}
</script>
<style scoped lang="scss">
.content {
background: #fff;
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.btnClose {
color: #fff;
background: linear-gradient(-90deg, #fccf4f, #fba418 80%) !important;
}
.baocun {
color: #fff;
background: linear-gradient(-90deg, #feaa50, #e96b13 80%) !important;
}
.quan {
width: 400rpx;
height: 400rpx;
border: 8px solid #feaa50;
border-radius: 50%;
margin: 15px auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0px 0px 25px 10px #e96b13;
animation: pulse 1s infinite;
.weight {
font-size: 50px;
color: #000;
font-weight: bold;
}
.typeInfo {
width: 100%;
text-align: center;
font-size: 16px;
color: #f0ae43;
}
}
@keyframes pulse {
0% {
box-shadow: 0px 0px 25px 10px #e96b13;
}
50% {
box-shadow: 0px 0px 25px 10px #fba418;
}
100% {
box-shadow: 0px 0px 25px 10px #e96b13;
}
}
.status {
width: 70%;
font-size: 16px;
height: 35px;
line-height: 35px;
text-align: center;
border-radius: 15px;
margin: 15px auto;
background-color: #ffdda6;
}
.disabled {
width: 150px;
background-color: #DFDFDF;
border: 1px solid #f7f7f7;
color: #fff;
text-align: center;
padding: 7px;
border-radius: 10px;
margin: 15px auto;
}
.tips {
font-size: 14px !important;
margin-bottom: 20px;
}
</style>

View File

@ -0,0 +1,285 @@
<template>
<view class="weightPages">
<view class="content ">
<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="/static/HC.png" class="image3"></image>
</view>
<view class="tips">
<view>提示</view>
<text>1.请确定设备已开机</text>
<text>2.请确定手机蓝牙及位置信息已打开</text>
</view>
</view>
<!-- 手动记录 -->
<view class="wrapper" v-if="isHeight">
<view class="bg"></view>
<view class="Blue">
<view class="h4">测量结果提示</view>
<view class="Blue-box">
本次测量身高为<text>{{height}}{{unit}}</text>
</view>
<view class="Blue-box">
上次测量体重为<input v-model="weight" type="digit" placeholder="请输入体重" />kg
</view>
<view class="Blue-btn Blue-close" @click="handleBack(1)">取消</view>
<view class="Blue-btn" @click="handleGetMeasure">保存测量结果</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
export default {
data() {
return {
text: "",
weight: "",
height: "",
deviceId: "",
macAddr: "",
unit: "cm",
Unload: false,
stopblue: true,
isHeight: false,
isConnection: 0,
isdevice: false
}
},
computed: {
...mapState(["user", "isConnected", "isBluetoothTyle"]),
info() {
return this.user
},
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
onUnload: function() {
let that = this
if (!that.Unload) {
clearTimeout(myTime)
that.stopBluetoothDevicesDiscovery() //
that.closeBluetoothAdapter()
console.log("页面返回onUnload")
}
},
onLoad(options) {
let that = this
that.text = ""
that.isdevice = options.isdevice
that.openBluetoothAdapter()
},
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) {
clearTimeout(myTime);
that.isHeight = true
}
}
},
methods: {
//
openBluetoothAdapter() {
let that = this
that.text = ""
that.stopblue = true
that.isHeight = false
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,
success: res => {
that.onBluetoothDeviceFound();
},
fail: res => {
that.isConnection = 2
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
}
});
},
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
if (device.name.indexOf("G02") !== -1) {
let value = that.$tools.ab2hex(device.advertisData, "")
let type = value.substring(22, 24)
let num = value.substring(28, 29)
let dw = value.substring(29, 30)
let data = parseInt(value.substring(24, 28), 16)
that.isConnection = 1
if (dw == "1") {
that.unit = "FT"
data = data * 2.54
}
if (num == "1") {
data = data / 10
}
if (num == "2") {
data = data / 100
}
if (num == "3") {
data = data / 1000
}
if (type == "01") {
clearTimeout(myTime);
that.text = "您的身高是:" + data + that.unit
let buffer = device.advertisData.slice(3, 9)
device.mac = new Uint8Array(buffer) // 广maciOSmac
let tempMac = Array.from(device.mac)
tempMac.reverse()
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
that.deviceId = device.deviceId
that.macAddr = device.macAddr
that.height = data
that.stopblue = false
return
}
return;
}
})
});
that.handleMyTime()
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.macAddr) {
clearTimeout(myTime);
that.text = ""
that.Unload = true
that.stopblue = true
that.isHeight = false
that.isConnection = 2
that.startBluetoothDeviceDiscovery()
that.closeBluetoothAdapter()
}
}, 30000);
},
/**
* 停止搜索蓝牙设备
*/
stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success: e => {
console.log("停止搜索蓝牙设备", e)
},
});
},
//
handleGetMeasure() {
let that = this
if (!that.weight) {
this.$tools.msg("请输入体重")
return
}
that.$model.getmeasurefunit({
adc: 0,
weight: that.weight,
height: that.height,
aud_id: that.info.id
}).then(res => {
that.isHeight = false
if (res.code == 0) {
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("GetBodyTrendList", {
aud_id: uni.getStorageSync('userid'),
s_time: that.startDate,
e_time: that.endDate
})
that.$tools.msg("测量成功")
} else {
that.$tools.msg("测量失败")
}
that.Unload = true
setTimeout(function() {
that.closeBluetoothAdapter()
uni.redirectTo({
url: "/pages/body/body?acd_id=2" + '&device=' + that.isdevice
})
}, 200)
})
},
//
handleBack(ind) {
let that = this
that.text = ""
that.Unload = true
that.stopBluetoothDevicesDiscovery()
that.closeBluetoothAdapter()
if (ind == 1) {
uni.redirectTo({
url: "/pages/body/body?acd_id=2" + '&device=' + that.isdevice
})
}
},
/**
* 断开蓝牙模块
*/
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: res => {
console.log('蓝牙模块关闭成功');
}
})
},
},
}
</script>
<style scoped lang="scss">
.image3 {
width: 200px !important;
height: 340px !important;
}
</style>

351
pageTwo/devices/G02.vue Normal file
View File

@ -0,0 +1,351 @@
<template>
<view class="weightPages">
<view class="content ">
<view class="status">{{textLink}}</view>
<view class="text">{{text}}</view>
<view class="image">
<image src="/pageTwo/static/HC.png" class="image3"></image>
</view>
<view class="tips">
<view>提示</view>
<text>1.请确定设备已开机</text>
<text>2.请确定手机蓝牙及位置信息已打开</text>
</view>
</view>
<!-- 手动记录 -->
<view class="wrapper" v-if="isHeight">
<view class="bg"></view>
<view class="Blue">
<view class="h4">测量结果提示</view>
<view class="Blue-box">
本次测量身高为<text>{{height}}{{unit}}</text>
</view>
<view class="Blue-box">
上次测量体重为<input v-model="weight" type="digit" placeholder="请输入体重" />kg
</view>
<view class="Blue-btn Blue-close" @click="handleHeight">重新测量</view>
<view class="Blue-btn" @click="handleGetMeasure">保存测量结果</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
export default {
data() {
return {
text: "",
weight: "",
height: "",
height2: "",
deviceId: "",
macAddr: "",
write: "",
notify: "",
unit: "cm",
Unload: false,
isHeight: false,
isConnection: 0,
isdevice: false,
textLink: ""
}
},
computed: {
...mapState(["user", "isConnected", "isBluetoothTyle"]),
userInfo() {
return this.user
}
},
onUnload: function() {
let that = this
if (!that.Unload) {
clearTimeout(myTime)
that.closeBLEConnection()
that.closeBluetoothAdapter()
console.log("页面返回onUnload")
}
},
onLoad(options) {
let that = this
that.weight = that.userInfo.weight
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) {
let text = '测量过程中已与设备连接中断,请重新连接设备再开始测量'
that.$tools.showModal(text)
}
},
isBluetoothTyle: function() {
let that = this
if (!that.isBluetoothTyle) {
let text = '蓝牙已关闭,请重新打开蓝牙后再开始测量'
that.$tools.showModal(text)
}
},
},
methods: {
//
createBLEConnection() {
let that = this;
uni.createBLEConnection({
deviceId: that.deviceId,
success: res => {
that.textLink = "蓝牙连接中"
setTimeout(function() {
that.getBLEDeviceServices()
}, 1000)
},
fail: res => {
that.textLink = "设备连接失败,返回首页重新连接"
console.log("设备连接失败,请重新连接", res, that.deviceId);
}
});
},
/**
* 获取设备的UUID
*/
getBLEDeviceServices() {
let serviceList = [];
let that = this;
uni.getBLEDeviceServices({
deviceId: that.deviceId,
success: res => {
console.log("获取设备的UUID成功", res, that.deviceId)
serviceList = res.services;
for (let i = 0; i < serviceList.length; i++) {
let service = serviceList[i];
if (service.uuid.indexOf("FFF0") != -1) {
that.serviceId = service.uuid;
that.getBLEDeviceCharacteristics();
console.log("设备的FFE0的serviceId " + that.serviceId);
break;
}
}
},
fail: res => {
that.textLink = "设备连接失败,返回首页重新连接"
console.log('获取设备的UUID失败:', res)
}
});
},
/**
* 获取指定服务的特征值
*/
getBLEDeviceCharacteristics() {
let that = this;
uni.getBLEDeviceCharacteristics({
deviceId: that.deviceId,
serviceId: that.serviceId,
success: res => {
// * read: true, //,write: true, //,notify: true
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
if (item.uuid.indexOf('0000FFF1') != -1) {
that.notify = item.uuid
} else if (item.uuid.indexOf('0000FFF2') != -1) {
that.write = item.uuid
}
}
that.textLink = "蓝牙连接成功,请开始测量"
uni.notifyBLECharacteristicValueChange({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.notify,
state: true,
})
uni.notifyBLECharacteristicValueChange({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.write,
state: true,
})
that.notifyBLECharacteristicValue()
},
fail: res => {
console.log('获取特征值失败:', JSON.stringify(res))
}
})
},
//
notifyBLECharacteristicValue() {
let that = this;
uni.notifyBLECharacteristicValueChange({
state: true, // notify
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.notify,
success(res) {
uni.onBLECharacteristicValueChange(function(res) {
let value = that.$tools.ab2hex(res.value, "");
let data = parseInt(value.substring(7, 10), 16)
let unit = parseInt(value.substring(10, 12))
let digit = parseInt(value.substring(12, 14))
if (digit == "1") {
data = data / 10
}
if (digit == "2") {
data = data / 100
}
if (unit == "0") {
that.unit = "cm"
}
if (unit == "1") {
that.unit = "inch"
}
if (unit == "2") {
that.unit = "ft"
}
if (Number(data) < 20) {
that.text = "操作错误,请重新测量"
} else {
if (unit == "2") {
let data1 = data / 12
let data2 = Number(data1 - Math.floor(data1)) * 12
that.height2 = data
that.height = Math.floor(data1) + "'" + data2.toFixed(1)
} else {
that.height2 = data
that.height = data
}
that.text = "您的身高是:" + that.height + that.unit
that.isHeight = true
}
console.log("G02", value, unit, data, that.height, that.height2)
})
},
fail(res) {
console.log("测量失败", res.value);
}
})
},
//
handleGetMeasure() {
let that = this
let height = 0
if (!that.weight) {
that.$tools.msg("请输入体重")
return
}
if (that.unit == 'ft') {
height = Number(that.height2 * 2.54).toFixed(2)
} else {
height = that.height2
}
console.log("提交身高", height)
that.$model.getmeasurefunit({
adc: 0,
weight: that.weight,
height: height,
aud_id: that.userInfo.id
}).then(res => {
that.isHeight = false
if (res.code == 0) {
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
that.$tools.msg("测量成功")
} else {
that.$tools.msg("测量失败")
}
that.Unload = true
uni.switchTab({
url: "/pages/home/home"
})
setTimeout(function() {
that.closeBLEConnection()
that.closeBluetoothAdapter()
}, 500)
})
},
handleHeight() {
let that = this
that.height = ""
that.text = ""
that.isHeight = false
// let j = Number(2 + 3).toString(16)
// let str = "5A0203" + j.substr(j.length - 2, 2)
// 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.write,
// value: buf.buffer,
// success: res => {
// console.log('', res.errMsg)
// },
// fail: res => {
// console.log("", res);
// },
// })
},
//
onBLEConnectionStateChange() {
let that = this
uni.onBLEConnectionStateChange(function(res) {
console.log("监听蓝牙连接状态", res.connected)
that.$store.commit("changeConnected", res.connected);
})
},
/**
* 断开蓝牙模块
*/
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: res => {
console.log('蓝牙模块关闭成功');
}
})
},
/**
* 断开蓝牙连接
*/
closeBLEConnection() {
var that = this;
uni.closeBLEConnection({
deviceId: that.deviceId,
success: res => {
console.log('断开蓝牙连接成功');
that.$store.commit("changeConnected", false);
}
});
},
},
}
</script>
<style scoped lang="scss">
.image3 {
width: 200px !important;
height: 340px !important;
}
.status {
width: 70%;
font-size: 16px;
height: 35px;
line-height: 35px;
text-align: center;
border-radius: 15px;
margin: 15px auto;
background-color: #ffdda6;
}
</style>

231
pageTwo/devices/PCL.vue Normal file
View File

@ -0,0 +1,231 @@
<template>
<view class="weightPages">
<view class="content ">
<view class="title">连接成功开始测量</view>
<view class="text">{{text}}</view>
<view class="image">
<image src="/pageTwo/static/PCL.gif" class="image3"></image>
</view>
<view class="tips">
<view>提示</view>
<text>1.请确定设备已开机</text>
<text>2.请确定手机蓝牙及位置信息已打开</text>
</view>
</view>
<!-- 手动记录 -->
<view class="wrapper" v-if="isHeight">
<view class="bg"></view>
<view class="Blue">
<view class="h4">测量结果提示</view>
<view class="Blue-box">
本次测量体重为<text>{{weight}}{{unit}}</text>
</view>
<view class="Blue-box">
上次测量身高为<input v-model="height" type="digit" placeholder="请输入身高" />cm
</view>
<view class="Blue-btn Blue-close" @click="handleBack">取消</view>
<view class="Blue-btn" @click="handleGetMeasure">保存测量结果</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
export default {
data() {
return {
text: "",
imp: "",
weight: "",
height: "",
deviceId: "",
unit: "kg",
Unload: false,
isHeight: false,
isConnection: 0,
isdevice: false,
stopblue: true,
}
},
computed: {
...mapState(["user"]),
info() {
return this.user
},
},
onUnload: function() {
let that = this
if (!that.Unload) {
clearTimeout(myTime)
that.closeBluetoothAdapter()
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
pages[pages.length - 2].$vm.getBlereload();
console.log("页面返回onUnload", pages, pages[pages.length - 2])
}
},
onLoad(options) {
let that = this
that.text = ""
that.stopblue = true
that.deviceId = options.deviceId
that.height = that.user.height
that.onBluetoothDeviceFound()
},
watch: {
stopblue: function() {
let that = this
if (!that.stopblue) {
clearTimeout(myTime);
that.isHeight = true
}
}
},
methods: {
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
device.advertisData = device.advertisData ? device.advertisData : ''
if (device.name.indexOf("PCL") !== -1 && device.deviceId.indexOf(that.deviceId) !=
-1) {
clearTimeout(myTime);
let value = that.$tools.ab2hex(device.advertisData, "")
let data = parseInt(value.substring(4, 8), 16)
let msg = parseInt(value.substring(16, 18), 16).toString(2)
let type = msg.substring(5, 6) //0,1
let num = msg.substring(3, 5) //
let dw = msg.substring(1, 3) //
if (dw == "01") {
that.unit = "斤"
}
if (dw == "10") {
that.unit = "lb"
}
if (num == "00") {
data = data / 10
}
if (num == "10") {
if (dw == "10") {
that.unit = "lb"
data = data / 10
} else {
data = data / 100
}
}
that.text = "您的实时体重是:" + data + that.unit
if (type == "1") {
that.text = "您的稳定体重是:" + data + that.unit
that.imp = parseInt(value.substring(8, 12), 16) / 10
that.deviceId = device.deviceId
that.weight = data
that.stopblue = false
return
}
return;
}
})
});
// that.handleMyTime()
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.macAddr) {
clearTimeout(myTime);
that.text = ""
that.Unload = true
that.isHeight = false
that.startBluetoothDeviceDiscovery()
that.closeBluetoothAdapter()
}
}, 30000);
},
/**
* 停止搜索蓝牙设备
*/
stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success: e => {
console.log("停止搜索蓝牙设备", e)
},
});
},
//
handleGetMeasure() {
let that = this
if (!that.height) {
this.$tools.msg("请输入身高")
return
}
that.$model.getmeasurefunit({
adc: that.imp,
weight: that.weight + that.unit,
height: that.height,
aud_id: that.info.id
}).then(res => {
that.isHeight = false
console.log("res", res, that.imp)
if (res.code == 0) {
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$tools.msg("测量成功")
} else {
that.$tools.msg("测量失败")
}
that.Unload = true
setTimeout(function() {
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
pages[pages.length - 2].$vm.getBlereload();
uni.switchTab({
url: "/pages/home/home"
})
}, 200)
})
},
//
handleBack() {
let that = this
that.text = ""
that.Unload = true
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
console.log("页面返回onUnload", pages, pages[pages.length - 2])
pages[pages.length - 2].$vm.getBlereload();
uni.switchTab({
url: "/pages/home/home"
})
},
/**
* 断开蓝牙模块
*/
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: res => {
console.log('蓝牙模块关闭成功');
}
})
},
},
}
</script>
<style scoped lang="scss">
.image3 {
width: 200px !important;
height: 340px !important;
}
</style>

244
pageTwo/devices/PCL22.vue Normal file
View File

@ -0,0 +1,244 @@
<template>
<view class="weightPages">
<view class="content ">
<view class="title">连接成功开始测量</view>
<view class="text">{{text}}</view>
<view class="image">
<image src="/pageTwo/static/PCL.gif" class="image3"></image>
</view>
<view class="tips">
<view>提示</view>
<text>1.请确定设备已开机</text>
<text>2.请确定手机蓝牙及位置信息已打开</text>
</view>
</view>
<!-- 手动记录 -->
<view class="wrapper" v-if="isHeight">
<view class="bg"></view>
<view class="Blue">
<view class="h4">测量结果提示</view>
<view class="Blue-box">
本次测量体重为<text>{{weight}}{{unit}}</text>
</view>
<view class="Blue-box">
上次测量身高为<input v-model="height" type="digit" placeholder="请输入身高" />cm
</view>
<view class="Blue-btn Blue-close" @click="handleBack">取消</view>
<view class="Blue-btn" @click="handleGetMeasure">保存测量结果</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
export default {
data() {
return {
text: "",
imp: "",
weight: "",
height: "",
deviceId: "",
unit: "kg",
Unload: false,
isHeight: false,
isConnection: 0,
isdevice: false,
stopblue: false,
typeInfo: -1
}
},
computed: {
...mapState(["user"]),
info() {
return this.user
},
},
onUnload: function() {
let that = this
if (!that.Unload) {
clearTimeout(myTime)
that.closeBluetoothAdapter()
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
pages[pages.length - 2].$vm.getBlereload();
console.log("页面返回onUnload", pages, pages[pages.length - 2])
}
},
onLoad(options) {
let that = this
that.text = ""
that.typeInfo = -1
that.stopblue = false
that.deviceId = options.deviceId
that.height = that.user.height
that.onBluetoothDeviceFound()
},
watch: {
stopblue: function() {
let that = this
if (!that.stopblue) {
clearTimeout(myTime);
that.isHeight = false
return
}
if (that.stopblue && that.typeInfo == 1) {
clearTimeout(myTime);
that.isHeight = true
}
}
},
methods: {
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
device.advertisData = device.advertisData ? device.advertisData : ''
let value = that.$tools.ab2hex(device.advertisData, "")
let type = value.substring(0, 2)
if (type.toLowerCase() == 'c0') {
clearTimeout(myTime);
let msg = parseInt(value.substring(16, 18), 16).toString(2)
let type = msg.substring(0, 1) // 01
let unit = msg.substring(1, 3) //
let num = msg.substring(3, 5) //
let weight = parseInt(value.substring(4, 8), 16)
let status = msg.substring(5, 6) //0,1
console.log("value", value, "状态:", status, "类型:", type, )
console.log('体重:', weight, "小数点:", num, "单位:", unit)
if (unit == "10") {
that.unit = "lb"
}
if (num == "00") {
weight = weight / 10
}
if (num == "10") {
if (unit == "10") {
that.unit = "lb"
weight = weight / 10
} else {
weight = weight / 100
}
}
if (status == "0") {
that.typeInfo = 0
that.stopblue = false
that.text = "您的实时体重是:" + weight + that.unit
}
if (status == "1") {
if (type == '1') {
that.imp = parseInt(value.substring(8, 12), 16) / 10
}
that.typeInfo = 1
that.text = "您的稳定体重是:" + weight + that.unit
that.weight = weight
that.stopblue = true
console.log("测量完成", that.weight)
}
return;
}
})
});
// that.handleMyTime()
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.macAddr) {
clearTimeout(myTime);
that.text = ""
that.Unload = true
that.isHeight = false
that.startBluetoothDeviceDiscovery()
that.closeBluetoothAdapter()
}
}, 30000);
},
/**
* 停止搜索蓝牙设备
*/
stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success: e => {
console.log("停止搜索蓝牙设备", e)
},
});
},
//
handleGetMeasure() {
let that = this
if (!that.height) {
this.$tools.msg("请输入身高")
return
}
that.$model.getmeasurefunit({
adc: that.imp,
weight: that.weight + that.unit,
height: that.height,
aud_id: that.info.id
}).then(res => {
that.isHeight = false
console.log("res", res, that.imp)
if (res.code == 0) {
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$tools.msg("测量成功")
} else {
that.$tools.msg("测量失败")
}
that.Unload = true
setTimeout(function() {
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
pages[pages.length - 2].$vm.getBlereload();
uni.switchTab({
url: "/pages/home/home"
})
}, 200)
})
},
//
handleBack() {
let that = this
that.text = ""
that.Unload = true
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
console.log("页面返回onUnload", pages, pages[pages.length - 2])
pages[pages.length - 2].$vm.getBlereload();
uni.switchTab({
url: "/pages/home/home"
})
},
/**
* 断开蓝牙模块
*/
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: res => {
console.log('蓝牙模块关闭成功');
}
})
},
},
}
</script>
<style scoped lang="scss">
.image3 {
width: 200px !important;
height: 340px !important;
}
</style>

223
pageTwo/devices/PCL22S.vue Normal file
View File

@ -0,0 +1,223 @@
<template>
<view class="weightPages">
<view class="content ">
<view class="title">连接成功开始测量</view>
<view class="text">{{text}}</view>
<view class="image">
<image src="/pageTwo/static/PCL.gif" class="image3"></image>
</view>
<view class="tips">
<view>提示</view>
<text>1.请确定设备已开机</text>
<text>2.请确定手机蓝牙及位置信息已打开</text>
</view>
</view>
<!-- 手动记录 -->
<view class="wrapper" v-if="isHeight">
<view class="bg"></view>
<view class="Blue">
<view class="h4">测量结果提示</view>
<view class="Blue-box">
本次测量体重为<text>{{weight}}{{unit}}</text>
</view>
<view class="Blue-box">
上次测量身高为<input v-model="height" type="digit" placeholder="请输入身高" />cm
</view>
<view class="Blue-btn Blue-close" @click="handleBack">取消</view>
<view class="Blue-btn" @click="handleGetMeasure">保存测量结果</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
export default {
data() {
return {
text: "",
imp: "",
weight: "",
height: "",
deviceId: "",
unit: "kg",
Unload: false,
isHeight: false,
isConnection: 0,
isdevice: false,
stopblue: false,
typeInfo: -1,
}
},
computed: {
...mapState(["user"]),
info() {
return this.user
},
},
onUnload: function() {
let that = this
if (!that.Unload) {
clearTimeout(myTime)
that.closeBluetoothAdapter()
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
pages[pages.length - 2].$vm.getBlereload();
console.log("页面返回onUnload", pages, pages[pages.length - 2])
}
},
onLoad(options) {
let that = this
that.text = ""
that.typeInfo = -1
that.stopblue = false
that.deviceId = options.deviceId
that.height = that.user.height
that.onBluetoothDeviceFound()
},
watch: {
stopblue: function() {
let that = this
if (!that.stopblue) {
clearTimeout(myTime);
that.isHeight = false
return
}
if (that.stopblue && that.typeInfo == '1') {
clearTimeout(myTime);
that.isHeight = true
}
}
},
methods: {
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
device.advertisData = device.advertisData ? device.advertisData : ''
if (device.name.toLowerCase().indexOf("da") !== -1) {
clearTimeout(myTime);
let value = that.$tools.ab2hex(device.advertisData, "")
let type = value.substring(0, 1) //de
let type2 = value.substring(1, 2) //0~9A~F
let weight = parseInt(value.substring(2, 6), 16) / 100
console.log("VALUE", value, type, isNaN(type2), weight)
if (type == "d") {
that.typeInfo = 0
that.stopblue = false
that.text = "您的实时体重是:" + weight + 'kg'
}
if (type == "e") {
that.typeInfo = 1
that.text = "您的稳定体重是:" + weight + 'kg'
that.imp = !isNaN(type2) ? parseInt(value.substring(6, 10), 16) : ''
that.weight = weight
that.stopblue = true
return
}
return;
}
})
});
// that.handleMyTime()
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.macAddr) {
clearTimeout(myTime);
that.text = ""
that.Unload = true
that.isHeight = false
that.startBluetoothDeviceDiscovery()
that.closeBluetoothAdapter()
}
}, 30000);
},
/**
* 停止搜索蓝牙设备
*/
stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
success: e => {
console.log("停止搜索蓝牙设备", e)
},
});
},
//
handleGetMeasure() {
let that = this
if (!that.height) {
this.$tools.msg("请输入身高")
return
}
that.$model.getmeasurefunit({
adc: that.imp,
weight: that.weight + that.unit,
height: that.height,
aud_id: that.info.id
}).then(res => {
that.isHeight = false
console.log("res", res, that.imp)
if (res.code == 0) {
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
that.$tools.msg("测量成功")
} else {
that.$tools.msg("测量失败")
}
that.Unload = true
setTimeout(function() {
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
pages[pages.length - 2].$vm.getBlereload();
uni.switchTab({
url: "/pages/home/home"
})
}, 200)
})
},
//
handleBack() {
let that = this
that.text = ""
that.Unload = true
that.stopBluetoothDevicesDiscovery() //
let pages = getCurrentPages();
console.log("页面返回onUnload", pages, pages[pages.length - 2])
pages[pages.length - 2].$vm.getBlereload();
uni.switchTab({
url: "/pages/home/home"
})
},
/**
* 断开蓝牙模块
*/
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: res => {
console.log('蓝牙模块关闭成功');
}
})
},
},
}
</script>
<style scoped lang="scss">
.image3 {
width: 200px !important;
height: 340px !important;
}
</style>

485
pageTwo/devices/PCT01.vue Normal file
View File

@ -0,0 +1,485 @@
<template>
<view class="content skipping">
<!--自由训练 -->
<view class="title">{{info.active==1?'自由跳':info.active==2?'倒计时':'倒计数'}}</view>
<view class="skiptop">
<view class="item">
<view class="item-ite">{{info.active==1?'自由次数':info.active==2?"个数":'目标次数'}}<text>{{weight}}</text>
</view>
<view class="item-ite">
{{info.active==2?'目标时长 分:秒':"分:秒"}}<text>{{time_m?time_m:'00'}}:{{time_s?time_s:'00'}}</text>
</view>
<view class="item-ite">消耗/kcal<text>{{Math.floor(kcal)}}</text></view>
</view>
</view>
<view class="image">
<image src="/pageTwo/static/t01.gif"></image>
</view>
<view class="end" @longpress="onlongpress">长按结束</view>
<!-- 报告 -->
<view class="wrapper" v-if="iswrapper">
<view class="bg">
<view class="edit">
<view class="editem">
<view>平均速度<text class="cyello Blue size20 mr-5">{{bpm.toFixed(1)}}</text>bpm</view>
<view class="size12 c999 ">(bpm=/分钟)</view>
</view>
<view class="center">
<view class="left">
<image src="/pageTwo/static/duan.png"></image>
<view class="name">
<view>
中断次数
</view>
<view>
<text class="cyello Blue size20 mr-5">{{Bcount}}</text>
</view>
</view>
</view>
<!-- -->
<view class="left">
<image src="/pageTwo/static/xu.png"></image>
<view class="name">
<view>
最长连续
</view>
<view>
<text class="cyello Blue size20 mr-5">{{continuous}}</text>
</view>
</view>
</view>
</view>
<view class="item">
<view class="item-ite"><text>{{weight}}</text>训练个数</view>
<view class="item-ite"><text>{{time_m?time_m:'00'}}:{{time_s?time_s:'00'}}</text>:</view>
<view class="item-ite"><text>{{Math.floor(kcal)}}</text>消耗/kcal</view>
</view>
<view class="btn" @click="handleTarget">完成</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let innerAudioContext = null;
export default {
data() {
return {
bpm: 0,
isend: false,
weight: 0,
Ycount: 0,
time_m: "",
time_s: "",
time: 0,
kcal: 0,
Bcount: 0,
continuous: 0,
info: {},
isToggle: false,
isEnd: false,
iswrapper: false,
isStart: false
}
},
computed: {
...mapState(["isConnected", "isBluetoothTyle"]),
},
onLoad(options) {
let that = this
innerAudioContext = uni.createInnerAudioContext()
if (options && options.info) {
let info = options.info
that.info = JSON.parse(info)
that.notifyBLECharacteristicValue()
setTimeout(function() {
that.handleStart('开始')
}, 900)
setTimeout(function() {
that.handleStart('连续')
}, 1200)
}
that.handleAudioStart()
that.$Bluetooth.onBLEConnectionStateChange()
uni.onBluetoothAdapterStateChange(function(res) {
that.$store.commit("changeBluetooth", res.available);
})
},
onUnload: function() {
let that = this
if (innerAudioContext) {
innerAudioContext.destroy(); //
}
that.handleEnd()
console.log("PCT01返回onUnload")
},
watch: {
isConnected: function() {
let that = this
if (!that.isConnected) {
uni.showModal({
title: '连接已断开',
content: '训练过程中已与设备连接中断,请重新连接设备再开始训练',
showCancel: false,
success: function(res) {
if (res.confirm) {
that.handleTarget()
}
}
})
console.log("蓝牙是否连接", that.isConnected)
}
},
isBluetoothTyle: function() {
let that = this
if (!that.isBluetoothTyle) {
console.log("蓝牙是否打开", that.isBluetoothTyle)
}
},
//
isStart: function() {
let that = this
if (that.isStart) {
that.handleAudio()
}
},
//
isToggle: function() {
let that = this
if (that.isToggle) {
uni.showModal({
title: '友情提示',
content: '训练过程中请勿切换训练,返回训练',
showCancel: false,
success: function(res) {
if (res.confirm) {
setTimeout(function() {
that.handleStart('结束')
}, 400)
setTimeout(function() {
that.handleTarget()
}, 600)
}
}
})
}
},
//
isEnd: function() {
let that = this
if (that.isEnd) {
setTimeout(function() {
that.handleStart('停止')
}, 200)
setTimeout(function() {
that.handleGetMeasure()
}, 400)
}
},
//
weight: function() {
let that = this
if (that.info.active == 1) {
that.$video.video.forEach(ite => {
if (Number(ite.name) == that.weight) {
innerAudioContext.autoplay = true;
innerAudioContext.loop = false;
innerAudioContext.src = ite.video;
innerAudioContext.play()
setTimeout(function() {
innerAudioContext.stop();
that.handleAudio()
}, 3000)
}
})
}
if (that.info.active == 2) {
let time = that.time_m * 60 + that.time_s
that.$video.video.forEach(ite => {
if ((Number(ite.name) == that.weight) && (Number(time) > 10)) {
innerAudioContext.autoplay = true;
innerAudioContext.loop = false;
innerAudioContext.src = ite.video;
innerAudioContext.play()
setTimeout(function() {
innerAudioContext.stop();
that.handleAudio()
}, 3000)
}
})
if (that.time_m == "00" && that.time_s == "10") {
innerAudioContext.autoplay = true;
innerAudioContext.loop = false;
innerAudioContext.src = '/pageTwo/static/time.mp3';
innerAudioContext.play()
setTimeout(function() {
innerAudioContext.stop();
that.handleAudio()
}, 3000)
}
}
if (that.info.active == 3) {
that.$video.video.forEach(ite => {
if ((Number(ite.name) == (Number(that.Ycount) - Number(that.weight))) && Number(that
.weight) != 0) {
innerAudioContext.autoplay = true;
innerAudioContext.loop = false;
innerAudioContext.src = ite.video;
innerAudioContext.play()
setTimeout(function() {
innerAudioContext.stop();
that.handleAudio()
}, 3000)
}
})
if (Number(that.weight) == 10) {
innerAudioContext.autoplay = true;
innerAudioContext.loop = false;
innerAudioContext.src = '/pageTwo/static/number.mp3';
innerAudioContext.play()
setTimeout(function() {
innerAudioContext.stop();
that.handleAudio()
}, 3000)
}
}
},
},
methods: {
handleAudioStart() {
let that = this
innerAudioContext.autoplay = true;
innerAudioContext.loop = false;
innerAudioContext.src = '/pageTwo/static/Start.mp3';
innerAudioContext.play()
setTimeout(function() {
innerAudioContext.stop();
that.handleAudio()
}, 5000)
},
handleAudio() {
innerAudioContext.autoplay = true;
innerAudioContext.loop = true;
innerAudioContext.src = '/pageTwo/static/flight.mp3';
innerAudioContext.play()
},
//
notifyBLECharacteristicValue() {
let that = this;
uni.notifyBLECharacteristicValueChange({
state: true, // notify
deviceId: that.info.deviceId,
serviceId: that.info.serviceId,
characteristicId: that.info.notify,
success(res) {
uni.onBLECharacteristicValueChange(function(res) {
let value = that.$tools.ab2hex(res.value, "");
let count = parseInt(value.substring(8, 12), 16)
let Ycount = parseInt(value.substring(12, 16), 16) //
let time = parseInt(value.substring(16, 20), 16) ///
let timeDown = parseInt(value.substring(20, 24), 16) //
let type = parseInt(value.substring(30, 32), 16) //
let weight = parseInt(value.substring(32, 34), 16) //
let kcal = parseInt(value.substring(34, 38), 16) //
let minutes = null
let seconds = null
if (type == 0 || type == 4) {
that.weight = count //
that.Ycount = Ycount
that.time = time
that.kcal = kcal / 10
if (that.info.active != 2 && count != 0) { // +
minutes = Math.floor((time % 3600) / 60)
seconds = time % 60
that.time_m = minutes > 9 ? minutes : '0' + minutes
that.time_s = seconds > 9 ? seconds : '0' + seconds
}
if (that.info.active == 2) { //
let T = Number(timeDown) - Number(time)
minutes = Math.floor((T % 3600) / 60)
seconds = T % 60
that.time_m = minutes > 9 ? minutes : '0' + minutes
that.time_s = seconds > 9 ? seconds : '0' + seconds
}
that.Bcount = parseInt(value.substring(24, 26), 16) //
that.continuous = parseInt(value.substring(26, 30), 16) //
console.log("自由模式", count, kcal, time, that.time_m, that.time_s, weight)
}
if ((type == 2 || type == 3) && !that.isToggle) {
setTimeout(function() {
that.isToggle = true
that.handleStart('停止')
}, 200)
console.log("当前状态被切换")
}
if (type == 4 && !that.isEnd) {
that.isEnd = true
console.log("当前状态被结束")
}
})
},
fail(res) {
console.log("测量失败", res.value);
}
})
},
SendData(str) {
let that = this
let buf = new Uint8Array(str.match(/[\da-f]{2}/gi).map(function(h) {
return parseInt(h, 16)
}))
uni.writeBLECharacteristicValue({
deviceId: that.info.deviceId,
serviceId: that.info.serviceId,
characteristicId: that.info.write,
value: buf.buffer,
success: res => {
console.log('下发指令成功', res.errMsg)
},
fail: res => {
console.log("下发指令失败", res);
},
})
},
onlongpress() {
let that = this
uni.vibrateLong({
success: function() {
console.log('短震动');
if (Number(that.time) < 10) {
uni.showModal({
title: '友情提示',
content: '本次跳绳时间低于10秒记录将不会被保存',
confirmText: "继续",
cancelText: "返回",
success: function(res) {
if (res.cancel) {
that.isStart = false
innerAudioContext.stop();
uni.navigateBack({ //
delta: 1
})
}
},
})
} else {
that.handleStart('停止')
setTimeout(function() {
that.handleStart('结束')
}, 400)
setTimeout(function() {
that.handleGetMeasure()
}, 800)
}
},
fail: function(err) {
console.error('震动失败:', err);
},
})
},
//
handleGetMeasure() {
let that = this
if (that.info.active == 3 && that.weight == 0 && that.Ycount != 0) {
console.log("1", that.weight, that.Ycount)
that.weight = that.Ycount
} else if (that.info.active == 3 && that.weight != 0 && that.Ycount != 0) {
console.log("2", that.weight, that.Ycount)
that.weight = Number(that.Ycount) - Number(that.weight)
}
if (that.info.active == 2) {
that.time_m = Math.floor((that.time % 3600) / 60)
that.time_s = that.time % 60
}
console.log("111111保存", that.weight, that.Ycount, that.time_m, that.time_s)
that.$model.getskipResult({
aud_id: uni.getStorageSync('userid'),
kcal: Math.floor(that.kcal),
num: that.weight,
time_m: Number(that.time_m),
time_s: that.time_s,
type: that.info.active == 1 ? 'free' : that.info.active == 2 ? 'time' : 'num'
}).then(res => {
console.log("保存", that.time, res)
that.isStart = false
innerAudioContext.stop()
if (res.code == 0) {
that.bpm = that.weight / (that.time / 60)
that.iswrapper = true
that.info.isSuccessful = true
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
} else {
that.$tools.msg(res.msg)
}
})
},
//
handleStart(text) {
let that = this
let j = null
let str = null
if (text == '连续') {
j = Number(165 + 5 + 3).toString(16)
str = "A5050300" + j.substr(j.length - 2, 2)
console.log("连续连续", str)
}
if (text == '停止') {
j = Number(165 + 5 + 3 + 5).toString(16)
str = "A5050305" + j.substr(j.length - 2, 2)
console.log("停止连续", str)
}
if (text == '开始') {
j = Number(165 + 5 + 5).toString(16)
str = "A5050500" + j.substr(j.length - 2, 2)
}
if (text == '结束') {
j = Number(165 + 5 + 5 + 1).toString(16)
str = "A5050501" + j.substr(j.length - 2, 2)
console.log("结束指令", str)
}
if (text == '继续') {
j = Number(165 + 5 + 4).toString(16)
str = "A5050400" + j.substr(j.length - 2, 2)
console.log("继续指令", str)
}
if (text == '暂停') {
j = Number(165 + 5 + 4 + 1).toString(16)
str = "A5050401" + j.substr(j.length - 2, 2)
console.log("暂停指令", str)
}
that.SendData(str)
},
handleTarget() {
let that = this
innerAudioContext.stop();
uni.navigateBack({ //
delta: 1
})
},
//
handleEnd() {
let that = this
that.handleStart('停止')
setTimeout(function() {
that.handleStart('结束')
}, 400)
setTimeout(function() {
uni.$emit('updateData', JSON.stringify(that.info))
}, 600)
}
}
}
</script>
<style lang="scss" scoped>
@import "./scss/PCT01.scss";
</style>

587
pageTwo/devices/PCV02.vue Normal file
View File

@ -0,0 +1,587 @@
<template>
<view class="content">
<view class="tips" v-if="!isstart">
<view class="top">
<view class="left cgreen f-l">T</view>
<view class="right">
<text class="cgreen">肺活量测试</text>
<text class="text">肺活量测试能让我们更好的了解您为您生成详细的健康报告</text>
</view>
</view>
<view class="list">
<view class="item" v-if="number1">
<text class="ml-10 mr-10">1</text>
<text>吸气肺活量</text>
<text class="cgreen">{{number1}}ml</text>
<text>吸气速度</text>
<text class="cgreen level">{{level1}}</text>
</view>
<view class="item" v-if="number2">
<text class="ml-10 mr-10">2</text>
<text>吸气肺活量</text>
<text class="cgreen">{{number2}}ml</text>
<text>吸气速度</text>
<text class="cgreen level">{{level2}}</text>
</view>
<view class="item" v-if="number3">
<text class="ml-10 mr-10">3</text>
<text>吸气肺活量</text>
<text class="cgreen">{{number3}}ml</text>
<text>吸气速度</text>
<text class="cgreen level">{{level3}}</text>
</view>
</view>
<view class="title" v-if="number3==''">
<view :class="[second==5?'cgreen':'']">您好<text>{{number1!=0?'二':number2!=''?'三':'一'}}</text>次测试开始
</view>
<view :class="[second==3?'cgreen':'']">放下呼吸训练器缓慢呼气尽可能排空肺部气体</view>
<view :class="[second==1?'cgreen':'']">使用呼吸训练器缓慢吸气直至到达极限</view>
</view>
<view class="data" v-if="number3">
<view class="val">
<text>{{average.toFixed(2)}}ml</text>
平均吸气肺活量
</view>
<view class="text">
根据您的个人信息您的达标吸气肺活量为{{standard}}ml您本次测试吸气速度{{averageS}}L/min,肺活量测试结果{{average.toFixed(2)}}ml结合您的身体状态和改善目标我们将为您生成详细的健康报告
</view>
</view>
<view class="btn" v-if="number3" @click="handleGetMeasure">查看本次报告</view>
<view class="btn close" v-if="number3" @click="isstart=true">我想重新测试</view>
<view class="btn" v-if="number1==0||number2==0||number3==0">
{{second}}S后开始第<text>{{number1!=0?'二':number2!=0?'三':'一'}}</text>次测试
</view>
</view>
<!-- 开始测量 -->
<view class="weight" v-else>
<view class="title cgreen">使用呼吸训练器缓慢吸气直至到达极限</view>
<view class="box1">
<view class="time">吸气速度 <text class="cgreen ml-5">{{LiuS}}L/min</text></view>
<view class="item">
<view class="image">
<!-- -->
<!-- <image src="../../static/01.gif" mode="widthFix"> -->
<!-- </image> -->
</view>
<view class="center mt-15">
<view class="level"></view>
<view class="level level-bg" :style="{'top':Number(100 - offset)+'%'}"></view>
<view class="level-item">
<view class="ite" v-for="(ite,ind) in list">{{ite.text}}</view>
</view>
</view>
</view>
<view class="val">
<text>{{text}}ml</text>吸气肺活量
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
let cnt = 0;
let count = 0;
let lastValue = null;
export default {
data() {
return {
isEnd: false,
isstart: false, //
number1: 0,
number2: 0,
number3: 0,
level1: "",
level2: "",
level3: "",
average: "", //
averageS: "", //
text: 0, //
LiuS: "", //
macAddr: "",
serviceId: "",
deviceId: "",
Unload: false,
notify: "",
write: "",
second: 5, //
standard: "", //
offset: 0, //
listS: [],
}
},
computed: {
...mapState(["user", "isConnected", "isBluetoothTyle", "lungLevel"]),
info() {
return this.user
},
list() {
let that = this
let standard = ""
that.lungLevel.forEach(ite => {
if (ite.text == "及格") {
standard = ite.min_val
}
})
that.standard = standard
return this.lungLevel
}
},
onUnload: function() {
let that = this
if (!that.Unload) {
clearTimeout(myTime)
that.stopBluetoothDevicesDiscovery() //
that.closeBLEConnection()
that.closeBluetoothAdapter()
console.log("页面返回onUnload")
}
},
onLoad(options) {
let that = this
if (options && options.deviceId) {
that.deviceId = options.deviceId
that.openBluetoothAdapter()
}
that.openBluetoothAdapter()
that.onBLEConnectionStateChange()
uni.onBluetoothAdapterStateChange(function(res) {
that.$store.commit("changeBluetooth", res.available);
})
},
watch: {
isConnected: function() {
let that = this
if (!that.isConnected) {
that.handleBack()
}
},
isBluetoothTyle: function() {
let that = this
if (!that.isBluetoothTyle) {
that.handleBack()
}
},
second: function() {
let that = this
if (that.second <= 0) {
cnt++
that.isstart = true
that.sendData("FA02A29E") //
that.offset = 0
that.text = 0
}
},
//
isEnd: function() {
let that = this
console.log("结束测量", that.isEnd)
if (that.isEnd) {
console.log("结束测量2", that.isEnd)
that.isstart = false
that.sendData("FA02A39F")
that.level3 = that.handlelenver(that.number2)
that.average = (Number(that.number3) + Number(that.number2) + Number(that.number1)) / 3
var sum = 0
for (var i = 0; i < that.listS.length; i++) {
sum += Number(that.listS[i]);
}
that.averageS = (sum / that.listS.length).toFixed(2)
console.log((sum / that.listS.length))
}
}
},
methods: {
//
openBluetoothAdapter() {
let that = this
cnt = 0
count = 0;
lastValue = null;
that.isEnd = false
that.text = 0
that.number1 = 0
that.number2 = 0
that.number3 = 0
that.level1 = ""
that.level2 = ""
that.level3 = ""
that.average = "" //
that.LiuS = "" //
that.second = 5 //
that.standard = "" //
that.offset = 0 //
uni.openBluetoothAdapter({
success: e => {
console.log("初始化设备")
that.startBluetoothDeviceDiscovery()
},
fail: e => {
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
}
});
},
//
startBluetoothDeviceDiscovery() {
let that = this
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
success: res => {
console.log("开始搜索")
that.onBluetoothDeviceFound();
},
fail: res => {
that.$tools.msg("请确定设备是开机状态、手机蓝牙权限已打开!")
}
});
},
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
if (device.name.indexOf('Yihejia_Lung') != -1) {
clearTimeout(myTime);
device.macAddr = device.deviceId
if (device.deviceId.indexOf(that.deviceId) != -1) {
that.stopBluetoothDevicesDiscovery()
that.createBLEConnection()
console.log("that.deviceId", that.deviceId, device.deviceId)
return;
}
}
})
});
that.handleMyTime()
},
//
createBLEConnection() {
let that = this;
uni.createBLEConnection({
deviceId: that.deviceId,
success: res => {
that.countdown()
setTimeout(function() {
that.getBLEDeviceServices()
}, 1500)
},
fail: res => {
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.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)
// * read: true, //,write: true, //,notify: true
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
if (item.uuid.indexOf('0000FFE9') != -1) {
that.write = item.uuid
} else if (item.uuid.indexOf('0000FFE4') != -1) {
that.notify = item.uuid
}
}
uni.notifyBLECharacteristicValueChange({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.notify,
state: true,
})
uni.notifyBLECharacteristicValueChange({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.write,
state: true,
})
uni.onBLECharacteristicValueChange(function(res) {
let value = that.$tools.ab2hex(res.value, "");
//
let LiuL = value.substring(14, 16) + value.substring(10, 14)
let LiuL2 = parseInt(LiuL, 16) / 1000
//
let LiuS = parseInt(value.substring(22, 26), 16) + parseInt(value
.substring(18, 22), 16)
let LiuS2 = LiuS / 1000
if (Number(LiuL2) > 0) {
that.text = LiuL2.toFixed(0)
that.LiuS = LiuS2.toFixed(1)
that.offset = that.handleoffset(that.text)
//
if (cnt == 1) {
//
if (that.text == lastValue) {
count++
if (count >= 30) {
that.isstart = false
that.sendData("FA02A39F") //
that.number1 = LiuL2.toFixed(0)
that.level1 = that.handlelenver(that.number1)
that.second = 5
that.countdown()
that.LiuS = 0
return
}
} else {
count = 0
lastValue = that.text // lastValue
}
}
if (cnt == 2) {
if (that.text == lastValue) {
count++
if (count >= 30) {
that.isstart = false
that.sendData("FA02A39F") //
that.number2 = LiuL2.toFixed(0)
that.level2 = that.handlelenver(that.number2)
that.second = 5
that.countdown()
that.LiuS = 0
return
}
} else {
count = 0
lastValue = that.text // lastValue
}
// console.log('2', cnt, LiuL2, count)
}
if (cnt == 3) {
//
if (that.LiuS != 0 || that.LiuS != 0.0) {
that.listS.push(that.LiuS)
}
//
if (that.text == lastValue) {
count++
if (count >= 15) {
that.number3 = LiuL2.toFixed(0)
that.isEnd = true
return
}
} else {
count = 0
lastValue = that.text // lastValue
}
console.log('流量3', cnt, count)
}
}
})
},
fail: res => {
console.log('获取特征值失败:', JSON.stringify(res))
}
})
},
//
sendData(str) {
let that = this
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.write,
value: buf.buffer,
success: res => {
console.log('下发指令成功', res.errMsg)
},
fail: res => {
console.log("下发指令失败", res);
},
})
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.macAddr) {
clearTimeout(myTime);
that.Unload = true
that.startBluetoothDeviceDiscovery()
that.closeBluetoothAdapter()
}
}, 30000);
},
//
handlelenver(value) {
let that = this
let text = ""
that.list.forEach(ite => {
if (Number(value) <= Number(ite.max_val) && Number(value) >= Number(ite.min_val)) {
text = ite.text
}
})
return text
},
//
handleoffset(value) {
let that = this
let number = 0
let length = that.list.length
number = value / (that.list[0].max_val - that.list[length - 1].min_val) * 100
return number.toFixed(0)
},
/**
* 停止搜索蓝牙设备
*/
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.closeBLEConnection()
that.closeBluetoothAdapter()
}
that.$store.commit("changeConnected", res.connected);
})
},
//
handleGetMeasure() {
let that = this
that.$model.getMeasureLung({
aud_id: uni.getStorageSync('userid'),
one: that.number1,
two: that.number2,
three: that.number3,
flow: that.averageS
}).then(res => {
if (res.code == 0) {
that.$store.dispatch('getUserInfo', {
aud_id: uni.getStorageSync('userid')
})
that.$store.dispatch("getLungResult", {
aud_id: uni.getStorageSync('userid')
})
}
that.Unload = true
setTimeout(function() {
that.closeBLEConnection()
that.closeBluetoothAdapter()
uni.switchTab({
url: "/pages/home/home"
})
}, 200)
})
},
//
handleBack(ind) {
let that = this
that.text = ""
that.Unload = true
that.stopBluetoothDevicesDiscovery()
that.closeBluetoothAdapter()
that.closeBLEConnection()
if (ind == 1) {
uni.switchTab({
url: "/pages/home/home"
})
}
},
// 5
countdown() {
let that = this
count = 0
lastValue = null
var timer = setInterval(function() {
that.second--;
}, 1000);
setTimeout(() => {
clearInterval(timer)
that.second = 0
}, 5000)
},
/**
* 断开蓝牙模块
*/
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">
@import "./scss/PCV02.scss";
.content {
width: calc(100% - 30px);
padding: 0 15px;
min-height: 100vh;
color: #5d5651;
background-color: #000;
}
</style>

View File

@ -0,0 +1,123 @@
.content {
width: 100%;
min-height: 100vh;
background-color: #fff;
}
.item-ite {
line-height: 20PX;
margin-bottom: 15px;
}
.title {
height: 50px;
line-height: 50px;
text-align: center;
font-weight: bold;
}
.image {
width: 100%;
text-align: center;
margin-top: 30px;
image {
width: 200px;
height: 252px;
margin: auto;
}
}
.end {
color: #fff;
position: absolute;
bottom: 80px;
width: 70px;
height: 70px;
line-height: 70px;
background: $btncolor;
margin-left: calc(50% - 35px);
border-radius: 50px;
text-align: center;
box-shadow: 0px 1px 5px 2px #dfe2e1fc;
}
.wrapper {
background-color: rgba(0, 0, 0, 0.6);
.edit {
width: 80% !important;
background-color: #fff;
}
.editem {
height: initial;
display: flex;
align-items: center;
flex-direction: column;
view {
width: 100%;
text-align: center;
margin-bottom: 5px;
}
}
.center {
background-color: #eee;
padding: 0 10px;
display: flex;
margin: 45px 0;
font-size: 32rpx;
border-radius: 5px;
height: 65px;
align-items: center;
justify-content: space-between;
image {
width: 35px;
height: 35px;
margin-right: 10px;
margin-top: 15px;
}
.left {
display: flex;
align-content: center;
}
.name {
margin-top: 15px;
}
}
.item {
display: flex;
justify-content: space-between;
.item-ite {
line-height: 20px;
font-size: 28rpx;
color: #999;
text-align: center;
text {
display: block;
width: 100%;
font-size: 36rpx;
color: #333;
text-align: center;
margin-bottom: 10px;
}
}
}
.btn {
margin-top: 25px;
height: 45px;
line-height: 45px;
background: $btncolor;
margin-bottom: 25px;
}
}

View File

@ -0,0 +1,222 @@
.cgreen {
color: #39D9C9;
}
.tips {
display: flex;
flex-direction: column;
justify-content: space-between;
.top {
width: 100%;
display: flex;
margin-top: 20px;
align-items: flex-start;
.left {
font-size: 64rpx;
margin-right: 10px;
}
.right {
.text {
font-size: 32rpx !important;
}
text {
font-size: 32rpx;
display: block;
width: 100%;
margin-bottom: 5px;
}
}
}
.item {
background-color: #272a2a;
border-radius: 10px;
margin-top: 8px;
color: #fff;
height: 35px;
line-height: 35px;
display: flex;
text {
flex-grow: 0;
display: inline-block;
}
.cgreen {
flex-grow: 2;
font-size: 32rpx;
text-align: center;
}
.level {
color: #516752;
}
}
.title {
font-size: 32rpx;
margin: 20px;
view {
width: 100%;
margin-top: 40px;
text-align: center;
}
}
.data {
margin-top: 20px;
.text {
font-size: 32rpx;
color: #fff;
line-height: 20px;
}
}
.btn {
width: 70%;
color: #fff;
padding: 5px 15px;
border-radius: 15px;
text-align: center;
background: $maincolor;
margin: 15px auto;
position: absolute;
bottom: 80px;
left: calc(15% - 15px);
}
.close {
background: #999;
bottom: 20px;
}
}
.weight {
padding-top: 30px;
.title {
width: 80%;
margin: auto;
font-size: 32rpx;
text-align: center;
}
}
.box1 {
color: #fff;
margin: 50px 15px 15px;
width: calc(100%- 30px);
.time {
width: 60%;
margin: auto;
position: relative;
text-align: center;
border-radius: 10px;
background-color: #272a2a;
height: 30px;
line-height: 30px;
}
.time:after {
content: "";
position: absolute;
left: 45%;
bottom: -7px;
width: 0px;
height: 0px;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 8px solid #272a2a;
}
.item {
width: 100%;
font-size:28rpx;
padding: 10px 0;
border-radius: 15px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 15px;
position: relative;
margin-top: 10px;
.image {
width: 80%;
image {
width: 100%;
margin-top: 10px;
}
}
.center {
top: 0px;
bottom: -15px;
position: absolute;
width: 55px;
margin: auto;
text-align: center;
background-color: #333;
border-radius: 10px;
z-index: 9;
}
.level-bg {
position: absolute;
width: 55px;
margin: auto;
text-align: center;
background-color: #4d6c7b;
border-radius: 0 0 10px 10px;
bottom: 0px;
z-index: 19;
}
.level-item {
width: 55px;
height: 100%;
position: absolute;
z-index: 99;
:last-child {
border-bottom: none;
}
}
.ite {
margin: 0 5px;
width: calc(100% - 10px);
height: 40px;
line-height: 40px;
font-size: 32rpx;
color: #fff;
z-index: 99;
border-bottom: 1px solid #999;
}
}
}
.val {
width: 100%;
text-align: center;
margin: 20px 0;
color: #fff;
font-size:28rpx;
text {
display: block;
color: #39D9C9 !important;
font-size: 64rpx;
margin-bottom: 10px;
}
}

View File

@ -0,0 +1,239 @@
.text {
position: absolute;
top: 0px;
width: 100%;
text-align: center;
height: 50px;
line-height: 50px;
font-size: 36rpx;
color: $textcolor;
font-weight: bold;
}
.tips {
position: absolute;
width: 100%;
bottom: 15px;
line-height: 24px;
view {
font-size: 32rpx;
color: $textcolor;
font-weight: bold;
margin-left: 15px;
}
text {
font-size: 32rpx;
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%;
background-color: #fff;
}
text {
display: block;
width: 100%;
font-size: 32rpx;
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);
}
}

205
pageTwo/devices/search.vue Normal file
View File

@ -0,0 +1,205 @@
<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.pic"></image>
<text>{{item.name}}</text>
</view>
</view>
<view class="tips" v-if="isdevTip">
<view>提示</view>
<text>1.请确定设备已绑定</text>
<text>2.请确定设备已开机</text>
<text>3.请确定手机蓝牙及位置信息已打开</text>
</view>
</view>
</template>
<script>
let that;
let myTime;
import {
mapState
} from "vuex";
export default {
data() {
return {
Unload: false, //
issearch: false, //
isdevTip: false, //
devicesList: [],
devList: [],
id: 0,
isdevice: true
}
},
computed: {
...mapState(["user", "isConnected", "isBluetoothTyle"]),
},
onLoad(options) {
that = this
that.id = options ? options.id : 0
that.isdevice = options.device
that.openBluetoothAdapter()
//
that.$Bluetooth.onBLEConnectionStateChange()
uni.onBluetoothAdapterStateChange(function(res) {
that.$store.commit("changeBluetooth", res.available);
})
},
onBackPress() {
let that = this
console.log("onUnload", that.Unload)
if (!that.Unload) {
that.$Bluetooth.closeBluetoothAdapter() //
that.$Bluetooth.stopBluetoothDevicesDiscovery() //
}
},
watch: {
isBluetoothTyle: function() {
let that = this
if (!that.isBluetoothTyle) {
that.issearch = true
that.isdevTip = true
that.devList = []
clearTimeout(myTime);
}
console.log("蓝牙是否打开", that.isBluetoothTyle)
}
},
methods: {
//
openBluetoothAdapter() {
let that = this
uni.openBluetoothAdapter({
success: e => {
console.log("蓝牙初始化成功")
that.issearch = false
that.isdevTip = false
that.devList = []
that.startBluetoothDeviceDiscovery()
},
fail: e => {
that.$Bluetooth.getBluetoothAdapter(e)
}
});
},
//
startBluetoothDeviceDiscovery() {
let that = this
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true, //
success: res => {
that.onBluetoothDeviceFound();
},
fail: res => {}
});
},
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
if (device.name.indexOf("G02") != -1) {
console.log("G02", device)
clearTimeout(myTime);
let buff = device.advertisData.slice(3, 9)
device.mac = new Uint8Array(buff) // 广maciOSmac
let tempMac = Array.from(device.mac)
tempMac.reverse()
device.macAddr = that.$tools.ab2hex(tempMac, ':').toUpperCase()
that.deviceId = device.macAddr
that.handleDevice(device)
return;
}
if (device.name.indexOf("Yihejia_Lung") != -1) {
console.log("肺活量PCV02", device)
clearTimeout(myTime);
device.macAddr = device.deviceId
that.deviceId = device.deviceId
that.handleDevice(device)
return;
}
if (device.name.indexOf("YPC") != -1) {
console.log("跳绳PCT02", device.name, device)
clearTimeout(myTime);
let buff = device.name.slice(7, 19)
device.macAddr = that.$tools.str2Num(buff)
device.deviceId = that.$tools.str2Num(buff)
that.deviceId = that.$tools.str2Num(buff)
if (device.macAddr != "") {
that.handleDevice(device)
}
return
}
})
});
that.handleMyTime()
},
handleDevice(device) {
let that = this
const foundDevices = that.devicesList
const idx = that.$tools.inArray(foundDevices, "deviceId", device.deviceId)
console.log("device", device, idx)
if (idx === -1) {
that.devicesList.push(device);
if (device.macAddr != "") {
that.handleDevType(device.macAddr)
}
}
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.devList.length) {
that.isdevTip = true
that.devList = []
}
that.issearch = true
clearTimeout(myTime);
that.$Bluetooth.stopBluetoothDevicesDiscovery()
}, 15000);
},
//
handleDevType(sn) {
that = this
that.$model.getdevdetail({
mac: sn,
acd_id: that.id
}).then(res => {
console.log("排查返回", res, sn, that.id)
if (res.code == 0) {
res.data.deviceId = sn
that.devList.push(res.data);
}
})
},
handleWeight(item) {
let that = this
clearTimeout(myTime);
that.Unload = true
console.log("跳转测量", item)
if (item.bluetooth_type == '透传') {
that.$Bluetooth.stopBluetoothDevicesDiscovery()
}
uni.redirectTo({
url: item.page_measure + '?deviceId=' + that.deviceId + '&isdevice=' + that.isdevice
})
},
}
}
</script>
<style scoped lang="scss">
@import "./scss/search.scss";
</style>

223
pageTwo/history/history.vue Normal file
View File

@ -0,0 +1,223 @@
<template>
<view class="common">
<view class="history" v-if="ranklist.length">
<view class="list" v-for="(item, index) in ranklist" :key="index" @click="clickItemMethod(item)">
<uni-swipe-action>
<uni-swipe-action-item :right-options="item.options" @click="swipeClick($event, index)">
<view class="time">
<icon class="t-icon t-icon-shijian-mianxing-0"></icon>
<text>{{item.record_time}}</text>
</view>
<view class="item">
<view>{{item.v1}}<text>{{item.v1_name}}</text></view>
<view v-if="item.v2">{{item.v2}}<text>{{item.v2_name}}</text></view>
<view v-if="item.v3">{{item.v3}}<text>{{item.v3_name}}</text></view>
<uni-icons type="right" v-if="acd_id!=6"></uni-icons>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<view class="endtext" v-if="!lastPage || page >= lastPage"> 到底了看看别的吧 </view>
</view>
<view class="nolist" v-if="!ranklist.length||!lastPage">
<image src="../../static/none.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
computed: {
...mapState(['user']),
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
data() {
return {
ranklist: [],
page: 1,
isDelete: false,
lastPage: '',
isActive: null,
acd_id: "",
}
},
onLoad(options) {
let that = this
that.acd_id = options.acd_id
that.getList()
console.log("options", options)
},
onUnload() {
console.log('关闭页面');
let that = this
var pages = getCurrentPages();
var Page = pages[pages.length - 1]; //
var prevPage = pages[pages.length - 2];
if (that.isDelete) { //
prevPage.$vm.reload()
}
},
onReachBottom() {
let that = this
console.log("onReachBottom", this.lastPage)
if (!this.lastPage || this.page >= this.lastPage) {
uni.showToast({
title: '没有更多数据!',
icon: 'none'
})
return
}
this.page++
this.getList(this.page)
},
methods: {
swipeClick(e, index) {
let that = this
let id = that.ranklist[index].id
uni.showModal({
title: '友情提示',
content: '是否删除当前测量记录?',
success: function(res) {
if (res.confirm) {
that.$model.gethistorydelete({
id: id,
type: that.acd_id,
}).then((res) => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.ranklist.splice(index, 1)
if (that.user.measure_model == "1") {
that.$store.dispatch("getUserInfo", {
aud_id: uni.getStorageSync('userid')
})
}
if (that.acd_id == 2) {
that.$store.dispatch("getResult", {
aud_id: uni.getStorageSync('userid')
})
} else {
that.isDelete = true
}
that.$tools.msg("删除成功")
})
} else if (res.cancel) {
that.$tools.msg("您已取消操作!");
}
},
})
},
clickItemMethod(item) {
let that = this
if (that.acd_id == "6") return
uni.navigateTo({
url: "/pageTwo/history/historyDetail?type=" + that.acd_id + '&id=' + item.id
})
},
getList(page) {
let that = this
that.$model.gethistory({
aud_id: uni.getStorageSync('userid'),
type: that.acd_id,
page: that.page,
}).then((res) => {
console.log("历史记录", res)
if (res.code != 0) return
let options = [{
text: '删除',
style: {
backgroundColor: '#dd524d'
}
}]
res.data.rows.forEach(item => {
item.options = options
})
this.ranklist = this.ranklist.concat(res.data.rows)
this.lastPage = res.data.totalpage
})
},
handleEdit(id) {
let that = this
that.isActive = that.isActive == id ? null : id
},
}
}
</script>
<style scoped="scoped" lang="scss">
.common {
width: 100%;
min-height: 100.5vh; //
overflow-y: scroll;
background-color: #f7f7f7;
}
.history {
width: calc(100% - 30px);
height: auto;
margin: 15px 15px 0;
padding-bottom: 40px;
.list {
width: 100%;
margin-top: 12px;
position: relative;
.item {
width: calc(100% - 20px);
height: auto;
background: #fff;
padding: 6px 10px;
display: flex;
justify-content: space-between;
border-radius: 10px;
align-items: center;
font-weight: 700;
line-height: 50rpx;
font-size: 36rpx !important;
text {
display: block;
color: #666;
text-align: center;
font-weight: 500;
font-size: 28rpx;
}
}
.time {
font-size: 28rpx;
color: #666;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
margin-bottom: 5px;
icon {
width: 40rpx;
height: 40rpx;
margin-right: 5px;
}
text {
font-size: 32rpx;
margin-top: 3px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
</style>

View File

@ -0,0 +1,117 @@
<template>
<view>
<view class="box">
<view class="form lanBox">
<view class="lan border-bottom" v-for="(item,index) in ranklist">
<view class="left">
<view class="view">
<view class="t-icon" :class="'t-icon-'+item.key_name" v-if="item.key_name!='score'&&item.key_name!='head_circumference'"></view>
<view class="score" v-if="item.key_name=='score'">A</view>
<image src="../../static/head.png" v-if="item.key_name=='head_circumference'"></image>
</view>
{{item.name}}
</view>
<view class="right">{{item.value?item.value:"0"}}{{item.unit}}</view>
</view>
</view>
</view>
</view>
</template>
<script>
// import {
// mapState
// } from "vuex";
export default {
data() {
return {
id: "",
type: "",
ranklist: []
};
},
// computed: {
// ...mapState([])
// },
onLoad(options) {
//
let that = this
that.id = options.id
that.type = options.type
that.getList()
},
methods: {
getList() {
let that = this
that.$model.gethistorydetail({
id: that.id,
type: that.type,
}).then((res) => {
console.log("历史记录详情", res)
this.ranklist = res.data
})
},
}
};
</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: 32rpx;
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: 32rpx;
padding-left: 30px;
.view {
width: 18px;
height: 18px;
position: absolute;
left: 15px;
padding: 2px;
background-color: #c7c7c7;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.t-icon,
image {
width: 16px;
height: 16px;
}
}
.right {
display: flex;
align-items: center;
justify-content: flex-end;
width: 50%;
min-height: 38px;
box-sizing: border-box;
line-height: 36px;
}
}
</style>

339
pageTwo/home/bmi.vue Normal file
View File

@ -0,0 +1,339 @@
<template>
<view class="content">
<view class="editem">
<view class="name">身高</view>
<view class="right">
<input type="digit" v-model="PostData.height" placeholder="请输入身高"
placeholder-style="font-size:13px;color:#666" />cm
</view>
</view>
<view class="edit">
<view class="editem">
<view class="name">体重</view>
<view class="right">
<input type="digit" v-model="PostData.weight" placeholder="请输入体重"
placeholder-style="font-size:13px;color:#666" />kg
</view>
</view>
<view class="editem">
<view class="name">性别</view>
<view class="right radio2">
<view class="radio">
<uni-icons :type="PostData.sex==1?'checkbox-filled':'circle'" @click="PostData.sex=1" size="24"
:color="PostData.sex==1?'#fea606':'#dfdfdf'"></uni-icons>
</view>
<view class="radio ml-15">
<uni-icons :type="PostData.sex==2?'checkbox-filled':'circle'" @click="PostData.sex=2" size="24"
:color="PostData.sex==2?'#fea606':'#dfdfdf'"></uni-icons>
</view>
</view>
</view>
<view class="editem">
<view class="name">出生日期</view>
<view class="right">
<picker mode="date" :value="PostData.birthday" :end="endDate" @change="bindDateChange"
:fields="fields">
<view class="text">{{PostData.birthday?PostData.birthday:"请选择出生日期"}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
</view>
<view class="box_con mb-15" v-if="iscalced">
<view class="BMIlist">
<view class="block">
<view class="name">
BMI
</view>
<view class="val">
{{resdata.bmi?resdata.bmi:'0'}}
</view>
<view class="btnf" :style="{backgroundColor:resdata.bmilevelcolor}">
{{resdata.bmilevel}}
</view>
</view>
<view class="desc">
<view class="statuevue">
<view class="bi">
<view :style="'left:'+resdata.offset+'%'" class="peobox">
<view class="xx"></view>
</view>
<view class="item" v-for="(ite , ind) in resdata.bmilevellist" :key="ind"
:style="{backgroundColor:ite.color}">
<view class="span1">{{ite.text}}</view>
<view class="span" v-if="ind<resdata.bmilevellist.length-1">{{ite.max_val}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="tip">
BMI是身体质量指数,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准
</view>
<view class="btn mt-20" @click="submit"> 立即计算</view>
</view>
</template>
<script>
export default {
data() {
return {
//
PostData: {
weight: '',
height: '',
sex: 0,
birthday: null
},
resdata: {
bmi: 0,
bmilevel: '',
bmilevelcolor: '',
bmilevellist: [],
offset: ""
},
//
sexItem: [
"男",
"女"
],
leftval: 0,
iscalced: false,
fields: "",
}
},
computed: {
endDate() {
return this.$tools.getDate("start")
},
},
onLoad() {
let that = this
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
methods: {
//
onsexArr(e) {
this.PostData.sex = this.sexItem[e.target.value] == "男" ? 1 : 2
},
//
bindDateChange(e) {
this.PostData.birthday = e.target.value
},
hideKeyboard() {
console.log("隐藏软键盘")
uni.hideKeyboard()
},
//bmi
submit() {
var that = this;
if (!that.PostData.weight) {
this.$tools.msg("请输入体重")
return;
}
if (!that.PostData.height) {
this.$tools.msg("请输入身高")
return;
}
if (!that.PostData.sex) {
this.$tools.msg("请选择性别")
return;
}
if (!that.PostData.birthday) {
this.$tools.msg("请选择年龄")
return;
}
that.$model.calcbmi(that.PostData).then(res => {
if (res.code == 0) {
this.resdata = res.data;
this.iscalced = true;
}
});
},
}
}
</script>
<style scoped lang="scss">
.content {
padding: 15px;
background-color: #fff;
}
.tip {
font-size: 24rpx;
color: #999;
line-height: 22px
}
.editem {
position: relative;
display: flex;
align-items: center;
font-size: 28rpx;
border-radius: 20px;
margin-bottom: 15px;
justify-content: space-between;
background: #eee;
padding-left: 15px;
.name {
width: 30%;
float: left;
height: 40px;
line-height: 40px;
}
.right {
width: 58%;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 15px;
height: 38px;
line-height: 38px;
.radio2 {
justify-content: space-between;
}
.radio {
width: 100%;
display: flex;
height: 40px;
line-height: 40px;
}
.text,
/deep/input {
position: absolute;
right: 15px;
top: 0;
left: 40%;
z-index: 9999;
color: #666;
text-align: left;
}
/deep/input {
padding-left: 0px;
margin-top: 0px;
font-size:30rpx !important;
height: 38px;
line-height: 38px;
}
}
}
.btn {
margin-top: 20px;
background-color: $maincolor;
}
.box_con {
margin-top: 15px;
padding: 10px 15px 15px;
border-radius: 10px;
display: flex;
flex-direction: column;
box-shadow: 0px 0px 5px 0px #c3c3c3;
font-size: 26rpx;
}
.desc {
line-height: 20px;
text-align: left;
width: calc(100%-20px);
height: auto;
border-radius: 5px;
font-size: 30rpx;
color: #999;
padding: 10px;
background: #f7f7f7;
.statuevue {
height: 35px;
position: relative;
width: 100% !important;
margin: 20px auto 10px;
.bi {
display: flex;
justify-content: space-between;
width: auto;
padding-top: 10px;
.peobox {
position: absolute;
right: 0;
top: -1px;
z-index: 999;
.xx {
width: 5px;
height: 5px;
border-radius: 50%;
background: #fff;
position: absolute;
z-index: 9;
border: 2px solid #1b2086;
top: 9px;
}
}
}
.item {
position: relative;
margin: 0;
flex: 1;
height: 5px;
color: #666;
font-size: 30rpx;
.span1 {
width: 100%;
text-align: center;
position: absolute;
top: -23px;
}
.span {
margin-top: 8px;
position: absolute;
right: -8px;
}
}
}
}
.block {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
align-items: center;
}
.btnf {
background-color: #ff5656;
padding: 3px 8px;
color: #fff;
border-radius: 5px;
}
.yuanxing {
display: inline-block;
background: #f19601;
width: 8px;
height: 12px;
margin-right: 5px;
font-size: 36rpx;
}
</style>

View File

@ -0,0 +1,300 @@
<template>
<view class="content">
<view class="top">
<text>成年身高预测</text>
为保证数据准确定请认真填写真实信息
</view>
<view class="table">
<view class="tr">
<view class="text">性别</view>
<view class="td">
<view class="radio">
<uni-icons :type="sex==1?'checkbox-filled':'circle'" @click="sex=1" size="24"
:color="sex==1?'#fea606':'#dfdfdf'"></uni-icons>
</view>
<view class="radio ml-10">
<uni-icons :type="sex==2?'checkbox-filled':'circle'" @click="sex=2" size="24"
:color="sex==2?'#fea606':'#dfdfdf'"></uni-icons>
</view>
</view>
</view>
<view class="tr">
<view class="text">出生日期</view>
<view class="td">
<picker mode="date" :end="endDate" @change="maskClick" :value="birthday?birthday:endDate"
:fields="fields">
<view class="uni-input">
{{birthday?birthday:'请选择'}}
<icon class="iconfont icon-arrow-down-bold"></icon>
</view>
</picker>
</view>
</view>
<view class="tr">
<view class="text">爸爸身高</view>
<view class="td">
<input class="input" type="digit" v-model="dadheight " placeholder="请输入">cm
</view>
</view>
<view class="tr">
<view class="text">妈妈身高</view>
<view class="td">
<input class="input" type="digit" v-model="momheight" placeholder="请输入">cm
</view>
</view>
</view>
<view class="table table2">
<view class="text">当前标准身高</view>
<view class="text">成年身高预测</view>
<view class="td">
<text>{{geneticheight}}</text>cm
</view>
<view class="td">
<text>{{adultheight}}</text>
<text class="text2" v-if="errorvalue">±{{errorvalue}}</text> cm
</view>
</view>
<view class="btn mb-15" @click="handleClick">立即计算</view>
<!-- <button open-type="share" class="share">
<icon class="t-icon t-icon-fenxiang"></icon>分享朋友测一测
</button> -->
<view class="title mt-20">
<view class="h5">如果当前实际身高当前标准身高</view>
<view class="con">孩子后天生长环境不利长高请从饮食睡眠运动情绪等方面排查加强后天因素管理让孩子处于最佳长高状态</view>
<view class="h5">如果当前实际身高当前标准身高</view>
<view class="con">孩子后天生长环境有利长高请继续保持加强后天因素管理孩子成年可比标准高10cm以上</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
sex: 1,
errorvalue: 0,
adultheight: 0,
geneticheight: 0,
dadheight: "",
momheight: "",
birthday: "",
fields: "",
}
},
computed: {
...mapState(["user"]),
endDate() {
return this.$tools.getDate("start")
},
},
onLoad() {
let that = this
// uni.showShareMenu({
// withShareTicket: true,
// menus: ["shareAppMessage"]
// })
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
// onShareAppMessage(res) {
// let that = this
// return {
// title: '?',
// path: '/pageTwo/share/shareHeight',
// imageUrl: '../../static/share1.jpg',
// success: function(res) {
// console.log("")
// },
// fail: function(res) {
// console.log("")
// },
// }
// },
methods: {
handleClick() {
let that = this
if (!that.dadheight) {
that.$tools.msg("请输入爸爸身高!");
return
}
if (!that.momheight) {
that.$tools.msg("请输入妈妈身高!");
return
}
uni.showLoading({
title: '计算中'
});
that.$model.GetPredictheight({
dadHeight: that.dadheight,
momHeight: that.momheight,
birthday: that.birthday,
sex: that.sex,
}).then(res => {
if (res.code != 0) return
setTimeout(function() {
uni.hideLoading();
}, 1000);
that.adultheight = res.data.adultheight
that.geneticheight = res.data.geneticheight
that.errorvalue = res.data.errorvalue
})
},
//
maskClick(e) {
this.birthday = e.detail.value
},
}
}
</script>
<style scoped lang="scss">
.content {
padding: 15px 10px;
background: #fff;
min-height: calc(100vh - 30px);
.radio {
display: flex;
height: 34px;
line-height: 34px;
}
picker {
width: 100%;
text-align: right;
border: none;
color: #333333;
}
.top {
width: 100%;
line-height: 30px;
font-size: 24rpx;
text-align: center;
margin-bottom: 30rpx;
color: #999;
text {
width: 100%;
display: block;
text-align: center;
font-size: 40rpx;
color: #333;
font-weight: 600;
}
}
.h5 {
font-size: 30rpx;
color: #666;
}
.con {
margin-top: 5px;
margin-bottom: 30rpx;
color: #999;
line-height: 22px;
font-size: 28rpx;
}
.table,
.table2 {
width: 100%;
border: 1px solid #d69231;
border-bottom: none;
box-sizing: border-box;
border-spacing: inherit;
font-size: 28rpx;
height: auto;
overflow: hidden;
border-right: none;
.tr {
width: 50%;
float: left;
.text {
width: 40%;
}
.td {
width: 60%;
}
}
.text {
float: left;
height: 35px;
line-height: 35px;
background: #ffcf85;
box-sizing: border-box;
border-bottom: 1px solid #d69231;
border-right: 1px solid #d69231;
text-align: center;
}
.td {
box-sizing: border-box;
background: #e4cdac21;
display: flex;
float: left;
height: 35px;
line-height: 35px;
padding-right: 5px;
padding-left: 5px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
border-bottom: 1px solid #d69231;
border-right: 1px solid #d69231;
text-align: center;
/deep/input {
width: 95%;
height: 35px;
line-height: 35px;
font-size: 30rpx !important;
}
}
}
.table2 {
margin: 50rpx auto;
border-right: none;
text-align: center;
.text {
width: 50%;
border-right: 1px solid #d69231;
}
.td {
height: 50px;
width: 50%;
line-height: 50px;
display: inherit;
border-right: 1px solid #d69231;
.text2 {
font-size: 36rpx;
font-weight: bold
}
}
}
}
.btn {
margin-top: 20px;
margin-bottom: 15px;
background-color: $maincolor;
}
</style>

67
pageTwo/login/detail.vue Normal file
View File

@ -0,0 +1,67 @@
<template>
<view class="content">
<view>
<view class="title">{{content.title}}</view>
<view class="time">发布时间{{content.createtime}}</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
content: "",
url: null
}
},
components: {
},
computed: {
...mapState(["user", "appTheme"]),
},
onLoad(option) { },
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>
.content {
padding: 30rpx;
}
.title {
width: 100%;
margin-bottom: 15px;
text-align: left;
font-size: 36rpx;
font-weight: bold;
}
.time {
width: 100%;
text-align: left;
margin-bottom: 15px;
color: #666;
}
</style>

View File

@ -0,0 +1,311 @@
<template>
<view class="content">
<!-- <view class="bg"></view> -->
<view class="login">
<view class="editem">
<view class="item">
<view class="text">手机号/邮箱</view>
<view class="input">
<input v-model="phone" type="text"/>
</view>
</view>
<view class="item ">
<view class="text">验证码</view>
<view class="input yanzhengma">
<input class="uni-input" v-model="code" />
<button class="code" type="none" @click="handleCode" v-model="code"
:disabled="disabled">{{second<60 ? second+'S后重发':$t("from.sendcode")}}
</button>
</view>
</view>
<view class="item">
<view class="text">密码</view>
<view class="input">
<input class="uni-input" v-model="password" />
</view>
</view>
<view class="item">
<view class="text">确认密码</view>
<view class="input">
<input class="uni-input" v-model="password2" />
</view>
</view>
</view>
<!-- <view class="xieyi">
<checkbox-group @change="checkboxChange" class="group">
<label>
<checkbox :value="1" style="transform:scale(0.7)" />{{$t("login.agreement")}}
<text @click="handlexieyi" @click.stop>{{$t("login.agreementContnt")}}</text>
</label>
</checkbox-group>
</view> -->
<view class="btnlogin" @click="handleTelLogin">确认</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
phone: "",
code: "",
password: "",
password2: "",
disabled: false,
second: 60,
value: 1,
type: ""
}
},
onLoad(options) {
this.type = options.type //1
},
methods: {
checkboxChange(e) {
this.value = e.detail.value.length ? e.detail.value[0] : "0"
},
//
handleTelLogin() {
let that = this
let phoneType = that.phone.indexOf("@") !== -1
if (that.value == 0) {
that.$tools.msg("请先确认勾选协议")
return
}
if (!phoneType && !(/^1[3456789]\d{9}$/.test(that.phone))) {
that.$tools.msg("请输入正确的手机号")
return
}
if (phoneType && !(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(that.phone))) {
that.$tools.msg("请输入正确的邮箱")
return
}
if (!that.code) {
that.$tools.msg("请填写验证码")
return
}
if (!that.password) {
that.$tools.msg("请填写密码")
return
}
if (!that.password2) {
that.$tools.msg("请确认密码")
return
}
if (that.password2 != that.password) {
that.$tools.msg("请确认两次密码填写一致")
return
}
let account = {
data: that.phone,
password: that.password,
c_password: that.password2,
code: that.code
}
let https = that.type == 'register' ? that.$model.getregister(account) : that.$model.getResetPassword(
account)
return https.then(res => {
console.log("注册", res)
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
uni.setStorageSync('token', res.data.token)
uni.setStorageSync('aan_id', res.data.aan_id)
that.$tools.msg("设置成功,进入程序中")
setTimeout(function() {
uni.reLaunch({
url: "/pages/home/home?type=1"
})
}, 1000)
}).catch(err => {})
},
//
handleCode() {
let that = this
let phoneType = that.phone.indexOf("@") !== -1
if (!phoneType && !(/^1[3456789]\d{9}$/.test(that.phone))) {
that.$tools.msg("请输入正确的手机号")
return
}
if (phoneType && !(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(that.phone))) {
that.$tools.msg("请输入正确的邮箱")
return
}
//
that.$model.getSendCode({
data: that.phone,
type: that.type
}).then(res => {
console.log(res)
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.disabled = true
let interval = setInterval(() => {
--that.second
}, 1000)
setTimeout(() => {
clearInterval(interval)
that.disabled = false
that.second = 60
}, 60000)
}).catch(err => {})
},
handlexieyi() {}
}
}
</script>
<style scoped lang="scss">
.content {
width: 100%;
height: 100vh;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
}
.bg {
position: absolute;
top: 0;
width: 100%;
height: 50vh;
z-index: 9;
// background: $maincolor;
}
.login {
width: calc(100% - 30px);
height: auto;
background: #fff;
border-radius: 10px;
padding: 15px;
background-color: #fff;
z-index: 99;
// position: relative;
// margin-left: calc(10% - 40px);
// box-shadow: 0px 1px 5px 2px #dfe2e1fc;
.title {
text-align: left;
color: #333;
font-size: 40rpx;
font-weight: bold;
margin-bottom: 15px;
}
.editem {
position: relative;
display: flex;
align-items: center;
font-size: 32rpx;
justify-content: space-between;
flex-wrap: wrap;
.item {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
.text {
width: 240rpx;
height: 40px;
line-height: 40px;
font-size: 32rpx;
}
.input {
width: calc(100% - 240rpx);
height: 35px;
line-height: 35px;
display: flex;
position: relative;
border: #dfdfdf 1px solid;
border-radius: 5px;
padding: 0 10px;
background-color: #f7f7f7;
}
input {
height: 40px;
line-height: 40px;
position: absolute;
left: 10px;
right: 0px;
z-index: 88;
font-size:28rpx;
}
.yanzhengma {
input {
right: 220rpx;
font-size:28rpx;
}
}
}
.code {
width: 220rpx;
background: #dfdfdf;
font-size: 28rpx;
margin: 0;
line-height: 40px;
border-radius: 5px;
text-align: center;
position: absolute;
right: 0px;
top: 0px;
bottom: 0;
z-index: 99;
}
.forget {
width: 80px;
background: #fff;
color: $textcolor;
}
}
.btngroup {
width: 100%;
height: 35px;
line-height: 35px;
display: flex;
justify-content: center;
text {
display: block;
color: $textcolor;
}
}
.btnlogin {
width: 100%;
margin: 15px 0;
height: 42px;
line-height: 42px;
background: $btncolor;
font-weight: 700;
border-radius: 15px;
text-align: center;
color: #fff !important;
}
}
.xieyi {
font-size: 32rpx;
color: $textcolor;
text {
border-bottom: 1px solid $textcolor;
}
}
</style>

306
pageTwo/login/login.vue Normal file
View File

@ -0,0 +1,306 @@
<template>
<view class="content">
<view class="bg"></view>
<view class="top">
<image src="../../static/logo2.png"></image>
<text>Reedaw</text>
</view>
<view class="login box_shadow">
<view class="title">登录</view>
<view class="toggle cblue" @click="handleToggle">
切换登录
</view>
<view class="editem">
<view class="item">
<view class="text">手机号/邮箱</view>
<view class="input">
<input v-model="phone" />
</view>
</view>
<!-- 验证码登录 -->
<view class="item " v-if="isCode">
<view class="text">验证码</view>
<view class="input yanzhengma">
<input class="uni-input" v-model="code" />
<button class="code" type="none" @click="handleCode" v-model="code"
:disabled="disabled">{{second<60 ? second+'S后重发':'获取验证码'}}
</button>
</view>
</view>
<!-- 密码登录 -->
<view class="item " v-else>
<view class="text">密码</view>
<view class="input">
<input class="uni-input" v-model="password" />
</view>
</view>
<view class="forget " v-if="!isCode">
<text @click="handlePassword('forgetPassword')">忘记密码?</text>
</view>
</view>
<view class="xieyi">
<checkbox-group @change="checkboxChange" class="group">
<label>
<checkbox :value="1" style="transform:scale(0.7)" />阅读并同意
<!-- <text @click.stop @click="handleUserXieyi" class="blue">用户协议</text> -->
<text @click.stop @click="handlexieyi" class="blue">隐私协议</text>
</label>
</checkbox-group>
</view>
<view class="btnlogin" @click="handleTelLogin">登录</view>
<view class="btngroup" @click="handlePassword('register')">
<text>注册</text>
</view>
</view>
<!-- #ifdef MP-WEIXIN -->
<view class="wxbtn">
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" v-if="value==1">
<view>
<image src="../../static/phone.png"></image>
</view>
<text>手机号快捷登录</text>
</button>
<button v-else @click="handleIsTel">
<view>
<image src="../../static/phone.png"></image>
</view>
<text>手机号快捷登录</text>
</button>
</view>
<!-- #endif -->
</view>
</template>
<script>
export default {
data() {
return {
phone: "",
code: "",
password: "",
disabled: false,
second: 60,
value: 0,
isCode: true,
loginCode: ""
}
},
onLoad() {
// #ifdef MP-WEIXIN
this.login()
// #endif
},
methods: {
//
checkboxChange(e) {
this.value = e.detail.value.length ? e.detail.value[0] : "0"
},
//
handleTelLogin() {
let that = this
let phoneType = that.phone.indexOf("@") !== -1
if (that.value == 0) {
that.$tools.msg("请先确认勾选协议")
return
}
if (!phoneType && !(/^1[3456789]\d{9}$/.test(that.phone))) {
that.$tools.msg("请输入正确的手机号")
return
}
if (phoneType && !(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(that.phone))) {
that.$tools.msg("请输入正确的邮箱")
return
}
if (that.isCode && !that.code) {
that.$tools.msg("请输入验证码")
return
}
if (!that.isCode && !that.password) {
that.$tools.msg('请输入正确密码')
return
}
this.$model.getonlogin({
data: that.phone,
validate_data: that.isCode ? that.code : that.password,
validate_type: that.isCode ? 'code' : 'password'
}).then(res => {
console.log("data", res.data)
that.$tools.msg(res.msg)
if (res.code != 0) return
that.$tools.msg("登录成功")
uni.setStorageSync('token', res.data.token)
uni.setStorageSync('aan_id', res.data.aan_id)
setTimeout(function() {
uni.reLaunch({
url: "/pages/home/home?type=1"
})
}, 1000)
}).catch(err => {})
},
//
handleCode() {
let that = this
let phoneType = that.phone.indexOf("@") !== -1
if (!phoneType && !(/^1[3456789]\d{9}$/.test(that.phone))) {
that.$tools.msg("请输入正确的手机号")
return
}
if (phoneType && !(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(that.phone))) {
that.$tools.msg("请输入正确的邮箱")
return
}
//
that.$model.getSendCode({
data: that.phone,
type: "login"
}).then(res => {
console.log(res)
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.disabled = true
let interval = setInterval(() => {
--that.second
}, 1000)
setTimeout(() => {
clearInterval(interval)
that.disabled = false
that.second = 60
}, 60000)
}).catch(err => {})
},
//
handleIsTel() {
if (this.value == 0) {
this.$tools.msg("请先确认勾选协议")
return
}
},
// code
login() {
let that = this
uni.login({
success(res) {
if (res.code) {
if (res.errMsg = "login:ok") {
that.loginCode = res.code
}
}
}
})
},
//
getPhoneNumber(res) {
const that = this
if (res.detail.errMsg == 'getPhoneNumber:ok') {
this.$model.getRegisterPhone({
code: that.loginCode,
encryptedData: res.detail.encryptedData,
iv: res.detail.iv,
}).then(res => {
if (res.code != 0) return
that.value = 1
uni.setStorageSync('token', res.data.token)
uni.setStorageSync('aan_id', res.data.aan_id)
setTimeout(function() {
uni.reLaunch({
url: "/pages/home/home?type=1"
})
}, 1000)
})
}
},
handleToggle() {
this.phone = ""
this.isCode = !this.isCode
},
handlePassword(text) {
uni.navigateTo({
url: "/pageTwo/login/forgetPassword?type=" + text
})
},
handlexieyi() {
let that = this
uni.navigateTo({
url: "/pageTwo/webview/webview?url=http://tc.pcxbc.com/technology/privacy_index"
})
},
handleUserXieyi() {
let that = this
}
}
}
</script>
<style scoped lang="scss">
@import "@/scss/login.scss";
.content {
width: 100%;
height: 100vh;
}
.xieyi {
font-size: 28rpx;
color: #999;
margin-left: 10px;
text {
color: $maincolor;
}
}
.href {
width: auto;
}
.wxbtn {
width: 100%;
position: absolute;
margin-top: 30px;
top: 80%;
icon {
font-size: 25px;
color: #28c445;
}
text {
display: block;
// width: 100%;
margin-top: 5px;
font-size: 12px;
// color: #666;
text-align: center;
border-bottom: 1px solid blue;
color: blue;
}
button {
line-height: initial;
background: #fff;
display: flex;
flex-wrap: wrap;
padding: 0;
justify-content: center;
}
button::after {
display: none;
}
view {
width: 100%;
}
image {
width: 30px;
height: 30px;
border-radius: 50%;
}
}
</style>

125
pageTwo/message/list.vue Normal file
View File

@ -0,0 +1,125 @@
<template>
<view class="content ">
<view v-if="list.length" class="tipsList">
<view class="list" v-for="(ite,ind) in list" :key="ind" @click="handleDetail">
<icon class="iconfont icon-tixing-copy"></icon>
<view class="info">
<view class="time">
<text class="name">{{ite.title}}</text>
<text class="date">{{ite.time}}</text>
</view>
<text class="des">{{ite.content}}</text>
</view>
</view>
<view class="endtext" v-if="!lastPage || page >= lastPage"> 到底了看看别的吧 </view>
</view>
<view class="nolist" v-if="!lastPage">
<image src="../../static/none.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [{
title: "驱虫",
type: 1,
time: "2023/05/15",
des: "哈哈哈哈或或或或",
static: 1
}],
page: 1,
lastPage: 0,
}
},
onLoad() {
let that = this
that.page = 1
},
onReachBottom() {
let that = this
if (!this.lastPage || this.page >= this.lastPage) {
uni.showToast({
title: '没有更多数据!',
icon: 'none'
})
return
}
this.page++
},
methods: {
getList(page) {
let that = this
that.$model.getHistoryList({
pageNo: this.page,
pageSize: 10,
}).then((res) => {
if (res.code != 0) return
this.list = this.list.concat(res.data.rows)
this.lastPage = res.data.totalpage
})
},
handleDetail() {}
}
}
</script>
<style lang="scss" scoped>
.content {
padding: 0 15px;
min-height: 100vh;
background-color: #f7f7f7;
}
.list {
margin-top: 15px;
background-color: #fff !important;
icon {
background-color: #f7f7f7;
border: 8px solid #f7f7f7;
position: relative;
}
icon::after {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
background-color: red;
position: absolute;
top: 0px;
right: 0px;
}
.time {
display: inline-block;
font-weight: bold;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.name {
color: #333;
width: 60%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-top: 0;
}
.date {
font-weight: 500;
font-size: 12px;
width: auto;
margin-top: 0;
float: right;
}
}
}
</style>

195
pageTwo/my/about.vue Normal file
View File

@ -0,0 +1,195 @@
<template>
<view class="content">
<view class="info">
<view class="logo">
<image src="../../static/logo2.png"></image>
<view>Reedaw</view>
<text>V{{phoneInfo.info.version}}</text>
</view>
<view class="list">
<view class="item" @click="handleVersion">
<view class="left">版本更新</view>
<view class="right">
<text class="new" v-if="version==-1">新版本{{phoneInfo.versionUrl.version}}</text>
<uni-icons type="right"></uni-icons>
</view>
</view>
<view class="item">
<a href="http://tc.pcxbc.com/technology/privacy_index" class="href">
<text class="left">隐私协议</text>
<uni-icons type="right"></uni-icons>
</a>
</view>
</view>
</view>
<!-- <view class="xieyi">
<a>隐私协议</a>
</view> -->
</view>
</template>
<script>
import {
mapState
} from "vuex";
let dtask;
export default {
data() {
return {
// 01-1
version: 0,
}
},
computed: {
...mapState(["phoneInfo"]),
},
onLoad() {
let that = this
if (!that.phoneInfo.versionUrl) {
console.log("111")
that.handleoginversion()
} else {
console.log("222")
that.version = that.$tools.compareVersions(that.phoneInfo.info.version, that.phoneInfo.versionUrl.version)
}
},
onBackPress() {
console.log("dtask", dtask)
if (dtask != undefined) {
dtask.onProgressUpdate((res) => {
if (res.progress != 100) {
dtask.abort();
}
});
}
},
methods: {
handleVersion() {
let that = this
if (that.version == -1) {
if (that.phoneInfo.platform === 'android') {
uni.setStorageSync('VERSION', that.phoneInfo.versionUrl.version)
let showLoading = plus.nativeUI.showWaiting('正在下载')
dtask = uni.downloadFile({
url: that.phoneInfo.versionUrl.url,
success: (downloadRes) => {
if (downloadRes.statusCode === 200) {
plus.nativeUI.closeWaiting()
plus.runtime.install(
downloadRes.tempFilePath, {
force: false
},
function() {
console.log('install success...');
plus.runtime.restart();
},
function(e) {
console.error('install fail...');
});
}
},
fail: () => {
uni.showToast({
title: '升级失败',
icon: 'none'
});
}
});
dtask.onProgressUpdate((res) => {
showLoading.setTitle(" 正在下载" + res.progress + "% ");
// console.log('' + res.progress + '%');
});
} else {
plus.runtime.launchApplication({
action: `itms-apps://itunes.apple.com/cn/app/id6654906497?mt=8`
})
}
} else {
that.$tools.msg("已经是最新版本了!")
}
},
//
handleoginversion() {
let that = this
that.$model.getloginversion({}).then(res => {
that.version = that.$tools.compareVersions(that.phoneInfo.info.version, res.data.version)
that.$store.commit('changePhoneInfo', {
versionUrl: res.data
})
})
},
}
}
</script>
<style scoped lang="scss">
.content {
min-height: calc(100vh - 30px);
padding: 15px;
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-between;
background-color: #f7f7f7;
}
.info {
width: 100%;
}
.logo {
width: 100%;
text-align: center;
font-size: 40rpx;
line-height: 35px;
image {
width: 140rpx;
height: 140rpx;
border-radius: 5px;
}
text {
display: block;
font-size: 32rpx;
color: #999;
}
}
.list {
width: calc(100% - 20px);
margin: 50px 0;
.item {
width: 100%;
height: 50px;
line-height: 50px;
margin-bottom: 15px;
display: flex;
background-color: #fff;
border-radius: 10px;
padding: 0 10px;
justify-content: space-between;
.new {
color: #fff;
background-color: red;
font-size: 32rpx;
border-radius: 10px;
padding: 3px 5px;
}
.href {
display: flex;
width: 100%;
color: #000;
text-decoration: none;
justify-content: space-between;
}
}
}
.xieyi {
color: $textcolor;
}
</style>

231
pageTwo/my/manage.vue Normal file
View File

@ -0,0 +1,231 @@
<template>
<view class="common">
<view class="add" @click="handleAddUser">
<icon class="iconfont icon-tianjia"></icon>添加成员
</view>
<view class="box" v-if="familayList.lenght!=0">
<view class="list">
<uni-swipe-action>
<uni-swipe-action-item v-for="(item ,index) in familayList" :key="index"
:right-options="item.options" @click="handleDeldet($event, index)">
<view class="item">
<view class="left">
<image :src="item.head_pic" class="image1" />
<view class="name">
<view class="title">
{{item.nickname}}
</view>
<view class="title2">
<text>{{item.gender==1?'男':'女'}}</text>
<text>{{item.age}}</text>
</view>
</view>
</view>
<view class="right" @click.stop>
<view class="blueBtn" @click="editorInfo(item)">编辑</view>
</view>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
<!-- <view class="left">
<image :src="item.head_pic" class="image1" />
<view class="name">
<view class="title">
{{item.nickname}}
</view>
<view class="title2">
<text>{{item.gender==1?'男':'女'}}</text>
<text>{{item.age}}</text>
</view>
</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() {},
onPullDownRefresh() {
let that = this
that.handleUserList()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000);
},
methods: {
//
handleDeldet(e, ind) {
let that = this
let id = that.familayList[ind].id
uni.showModal({
title: '友情提示',
content: '确定删除该成员吗',
success: function(res) {
if (res.confirm) {
that.$model.getDelUser({
id: id,
}).then(res => {
if (res.code != 0) return
that.$tools.msg("删除成功!");
that.familayList.splice(ind, 1)
that.handleUserList()
})
} else if (res.cancel) {
that.$tools.msg("您已取消删除!");
}
}
});
},
handleUserList() {
let that = this
that.$model.getUserList({
type: 2
}).then(res => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.$store.commit('changeFamilay', res.data)
if (res.data.length) {
uni.setStorageSync('userid', res.data[0].id)
that.$store.dispatch('getUserInfo', {
aud_id: res.data[0].id
})
that.handlePublicRecord(res.data[0].id)
}
}).catch(err => {})
},
//
handlePublicRecord(id) {
let that = this
that.$model.getPublicRecord({
aud_id: id
}).then(res => {
console.log("公共手动记录", res)
if (res.code == 0) {
that.$store.commit('changePublicRecord', res.data)
}
})
},
//
editorInfo(item) {
console.log("familayList", this.familayList)
uni.navigateTo({
url: "/pageTwo/my/userInfo?info=" + JSON.stringify(item)
})
},
//
handleAddUser() {
uni.navigateTo({
url: "/pageTwo/my/userInfo"
})
},
}
}
</script>
<style scoped="scoped" lang="scss">
.common {
padding: 15px;
background-color: #f7f7f7;
min-height: calc(100vh - 30px);
}
.add {
width: 100%;
height: 40px;
line-height: 40px;
font-size: 32rpx;
margin-bottom: 10px;
color: #fff;
border-radius: 15px;
display: flex;
justify-content: center;
background: $btncolor;
}
.box {
width: 100%;
height: auto;
margin: 15px 0;
padding-bottom: 40px;
}
.list {
width: 100%;
font-size: 36rpx;
.item {
background: #fff;
padding: 10px 15px;
width: calc(100% - 30px);
border-radius: 10px;
margin-top: 15px;
display: flex;
align-items: center;
justify-content: space-between;
}
.left {
width: 75%;
display: flex;
align-items: center;
.image1 {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
margin-right: 15px;
display: block;
}
.name {
width: calc(100% - 70px);
.title {
font-size: 34rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-top: 5px;
}
.title2 {
font-size: 32rpx;
color: #999;
margin-top: 15px;
text {
margin-right: 10px;
}
}
}
}
.blueBtn {
width: auto;
font-size: 32rpx;
text-align: center;
}
}
</style>

508
pageTwo/my/userInfo.vue Normal file
View File

@ -0,0 +1,508 @@
<template>
<view class="box">
<view class="lanBox">
<view class="headbox">
<view class="touxiang">
<image v-if="headimg" :src="headimg" class="headimage" />
<icon v-else class="iconfont icon-user-filling headimage"></icon>
</view>
</view>
<view class="lan border-bottom">
<view class="left">姓名</view>
<view class="right">
<input name="name" type="text" v-model="memInfo.nickname" placeholder="请输入姓名" />
<uni-icons type="clear" color="#999" v-if="memInfo.nickname" @click="memInfo.nickname=''"
size="20"></uni-icons>
</view>
</view>
<view class="lan border-bottom">
<view class="left">性别</view>
<view class="right">
<view class="radio">
<uni-icons :type="memInfo.gender==1?'checkbox-filled':'circle'" @click="memInfo.gender=1"
size="24" :color="memInfo.gender==1?'#fea606':'#dfdfdf'"></uni-icons>
</view>
<view class="radio ml-15">
<uni-icons :type="memInfo.gender==2?'checkbox-filled':'circle'" @click="memInfo.gender=2"
size="24" :color="memInfo.gender==2?'#fea606':'#dfdfdf'"></uni-icons>
</view>
<!-- <picker mode="selector" :range="sexItem" @change="onsexArr">
<view class="uni-input">{{memInfo.gender==0?'请选择':memInfo.gender==1?'男':'女'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker> -->
</view>
</view>
<view class="lan border-bottom">
<view class="left">身高</view>
<view class="right">
<input name="name" class="mr-5" type="digit" v-model="memInfo.height" placeholder="请输入身高" />CM
<uni-icons type="clear" color="#999" v-if="memInfo.height" @click="memInfo.height=''"
size="20"></uni-icons>
</view>
</view>
<view class="lan border-bottom">
<view class="left">体重</view>
<view class="right">
<input name="name" type="digit" class="mr-5" v-model="memInfo.weight" placeholder="请输入体重" />KG
<uni-icons type="clear" color="#999" v-if="memInfo.weight" @click="memInfo.weight=''"
size="20"></uni-icons>
</view>
</view>
<view class="lan border-bottom">
<view class="left">出生日期</view>
<view class="right">
<picker mode="date" :end="endDate" @change="maskClick"
:value="memInfo.birthday?memInfo.birthday:endDate" :fields="fields">
<view class="uni-input">{{memInfo.birthday?memInfo.birthday:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<view class="lan border-bottom">
<view class="left">场景选择</view>
<view class="right">
<view class="radio">
<uni-icons :type="memInfo.measure_model==1?'checkbox-filled':'circle'"
@click="handleMeasureModel(1)" size="24"
:color="memInfo.measure_model==1?'#fea606':'#dfdfdf'"></uni-icons>
</view>
<view class="radio ml-15">
<uni-icons :type="memInfo.measure_model==2?'checkbox-filled':'circle'"
@click="handleMeasureModel(2)" size="24"
:color="memInfo.measure_model==2?'#fea606':'#dfdfdf'"></uni-icons>
</view>
</view>
</view>
<view class="lan border-bottom" v-if="memInfo.measure_model==1">
<view class="left">身份信息</view>
<view class="right">
<picker mode="selector" :range="identityList" :value="identityIndex" range-key="name"
@change="changegIdentity">
<view class="uni-input">{{identityList[identityIndex]?identityList[identityIndex].name:"请选择"}}
</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
<view class="lan border-bottom" @click="handleCityList" v-if="memInfo.measure_model==1">
<view class="left">所属地区</view>
<view class="right">
<view class="mr-10">{{memInfo.address?memInfo.address:'请选择'}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</view>
</view>
<view class="lan border-bottom" v-if="memInfo.measure_model==1">
<view class="left">所在年级</view>
<view class="right">
<picker mode="selector" :range="gradeList" :value="gradeIndex" range-key="name"
@change="changegType">
<view class="uni-input">{{gradeList[gradeIndex]?gradeList[gradeIndex].name:"请选择"}}</view>
<icon class="iconfont icon-arrow-down-bold"></icon>
</picker>
</view>
</view>
</view>
<view class="btn" @click="confirmInfo">提交</view>
<!-- 地区 -->
<view v-if="visible" class="visible" @click="visible=false">
<view @click.stop class="item">
<view class="groupBtn">
<view @click="visible=false">取消</view>
<view @click="handlesure()" class="sure">确定</view>
</view>
<picker-view @change="bindChange" :value="value" class="picker-view" :indicator-style="indicatorStyle">
<picker-view-column>
<view class="item" v-for="(item,index) in province" :key="index">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in city" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
isEdit: false,
fields: "",
sexItem: [
"男",
"女"
],
memInfo: {
measure_model: 2,
birthday: "",
gender: 1,
nickname: "",
grade: "nothing",
height: "",
weight: "",
address: '',
identity_name: "陌生人",
identity_id: "P0",
},
visible: false,
province: [], //
city: [], //
area: [], //
value: [2, 0],
headimg: "",
identityIndex: 0,
gradeIndex: 0,
indicatorStyle: `height: 45px;`,
};
},
computed: {
...mapState(["user", "familayList", "cityList", "gradeList", "identityList"]),
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
onLoad(options) {
let that = this
that.handleIdentityList()
if (options.info) {
let info = JSON.parse(options.info)
that.memInfo = info
// if (info.measure_model == "1" || info.measure_model == 1) {
console.log("that.memInfo ", that.memInfo)
that.gradeIndex = that.gradeList.findIndex((profile) => profile.id === that.memInfo.grade);
that.memInfo.grade = that.gradeList[that.gradeIndex].id
that.identityIndex = that.identityList.findIndex((profile) => profile.id === that.memInfo.identity_id);
console.log("1111111111", that.identityList, that.identityIndex)
// }
that.isEdit = true
}
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
methods: {
//
confirmInfo() {
let that = this
if (!that.memInfo.nickname) {
that.$tools.msg("请输入姓名")
return;
}
if (!that.memInfo.height) {
that.$tools.msg("请选择身高")
return;
}
if (!that.memInfo.weight) {
that.$tools.msg("请选择体重")
return;
}
if (!that.memInfo.birthday) {
that.$tools.msg("请选择出生日期")
return;
}
if (that.memInfo.measure_model == 1 && !that.memInfo.identity_id) {
that.$tools.msg("请选择身份信息")
return;
}
if (that.memInfo.measure_model == 1 && !that.memInfo.address) {
that.$tools.msg("请选择所属地区")
return;
}
let https = that.isEdit ? that.$model.getEditUser(that.memInfo) : that.$model.getAddUser(that.memInfo)
return https.then(res => {
console.log("成功", res)
if (res.code == 0) {
that.$tools.msg("提交成功");
that.handleUserList(res.data.aud_id)
} else {
that.$tools.msg(res.msg);
}
});
},
handleUserList(id) {
let that = this
that.$model.getUserList({
type: 2
}).then(res => {
console.log("成员列表", res)
that.$store.commit('changeFamilay', res.data)
let aud_id = ""
let pages = getCurrentPages()
let prevPage = pages[pages.length - 2]
//
if (that.isEdit && that.memInfo.id == uni.getStorageSync('userid')) {
console.log("修改用户")
aud_id = uni.getStorageSync('userid')
}
//
if (!that.isEdit) {
console.log("添加用户")
uni.setStorageSync('userid', id)
uni.setStorageSync('gender', that.memInfo.gender)
aud_id = id
}
that.handlePublicRecord(aud_id)
that.$store.dispatch('getUserInfo', {
aud_id: aud_id
})
that.$store.dispatch("getResult", {
aud_id: aud_id
})
console.log("familayList个数", that.familayList.length)
if (!that.isEdit && that.familayList.length == 1) {
uni.setStorageSync('isBle', true)
uni.switchTab({
url: "/pages/home/home"
})
} else {
uni.navigateBack()
}
}).catch(err => {})
},
//
handlePublicRecord(id) {
let that = this
that.$model.getPublicRecord({
aud_id: id
}).then(res => {
console.log("公共手动记录", res)
if (res.code == 0) {
that.$store.commit('changePublicRecord', res.data)
}
})
},
//
maskClick(e) {
console.log("出生日期", e.detail.value)
this.memInfo.birthday = e.detail.value
},
//
onsexArr(e) {
this.memInfo.gender = this.sexItem[e.target.value] == "男" ? 1 : 2
},
//
changegType(e) {
this.gradeIndex = e.detail.value
this.memInfo.grade = this.gradeList[e.target.value].id
},
//
changegIdentity(e) {
let that = this
that.identityIndex = e.detail.value
that.memInfo.identity_id = that.identityList[e.detail.value].id
that.memInfo.identity_name = that.identityList[e.detail.value].name
},
//
bindChange(e) {
let that = this
if (e.detail.value[0] != that.value[0]) {
e.detail.value[1] = 0
}
that.value = e.detail.value
that.city = that.province[that.value[0]].list
},
handlesure() {
let that = this
let defaultRegion = [that.province[that.value[0]].name, that.city[that.value[1]]]
that.memInfo.address = defaultRegion.join(",");
that.visible = false
},
handleCityList() {
let that = this
that.province = that.cityList
if (that.user.address != '') {
let str = that.user.address.split(',')[0]
let str2 = that.user.address.split(',')[1]
var Index0 = that.cityList.findIndex((profile) => profile.name === str);
var Index2 = that.cityList[Index0].list.findIndex((ite) => ite === str2);
that.value[0] = Index0
that.value[1] = Index2
that.city = that.cityList[Index0].list
} else {
that.value = [2, 0]
that.city = that.cityList[2].list
}
that.visible = true
},
//
// handleGradeList() {
// let that = this
// if (that.isEdit == true) {
// that.gradeIndex = that.gradeList.findIndex(ite => ite.id == that.memInfo.grade)
// that.memInfo.grade = that.gradeList[that.gradeIndex].id
// }
// },
//
handleIdentityList() {
let that = this
if (that.isEdit == true) {
that.identityIndex = that.identityList.findIndex(ite => ite.id == that.memInfo.identity_id)
that.memInfo.identity_id = that.identityList[that.identityIndex].id
that.memInfo.identity_name = that.identityList[that.identityIndex].name
}
},
//
handleMeasureModel(ind) {
let that = this
that.memInfo.measure_model = ind
},
},
};
</script>
<style scoped="scoped" lang="scss">
.box {
height: 100vh;
background-color: #fff;
}
input {
border: none;
background: inherit;
}
.headbox {
height: 180rpx;
padding-top: 10px;
border-radius: 0 0 5px 5px;
background: $maincolor;
}
.headimage {
display: block;
padding-top: 10px;
width: 70px;
height: 70px;
border-radius: 50%;
font-size: 140rpx;
margin: auto;
color: #fff;
}
.lan {
display: flex;
align-items: center;
font-size: 32rpx;
padding: 5px 0;
margin: 5px 15px;
border-bottom: 1px solid #f7f7f7;
}
.left {
width: 24%;
text-align: left;
}
.right {
display: flex;
align-items: center;
justify-content: flex-end;
width: 72%;
height: 40px;
line-height: 40px;
box-sizing: border-box;
position: relative;
text-align: right;
.radio {
display: flex;
align-items: center;
}
picker {
width: 100%;
text-align: right;
border: none;
margin-right: 15px;
font-size: 32rpx;
color: #333333;
}
/deep/input {
height: 35px;
padding-top: 1px;
font-size: 32rpx;
color: #333333;
margin-right: 15px;
}
.iconfont {
color: #333333;
font-size: 32rpx;
position: absolute;
right: -10px;
top: 0;
}
}
.btn {
width: auto;
margin: 40px 15px 0;
background: $btncolor !important;
}
.visible {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
background-color: rgba(0, 0, 0, 0.6);
.groupBtn {
height: 50px;
line-height: 50px;
background-color: #fff;
display: flex;
justify-content: space-between;
padding: 0 15px;
border-bottom: 1px solid #dfdfdf;
position: absolute;
left: 0;
right: 0;
bottom: 45%;
z-index: 999;
view {
height: 30px;
line-height: 30px;
padding: 0 10px;
background-color: #dfdfdf;
border-radius: 5px;
margin-top: 10px;
}
.sure {
background-color: $textcolor;
color: #fff !important;
}
}
.picker-view {
width: 100%;
height: 45%;
bottom: 0;
position: absolute;
background-color: #fff;
}
.item {
line-height: 45px;
text-align: center;
}
}
</style>

View File

@ -0,0 +1,100 @@
<template>
<view class="content addText">
<view class="item">
<!-- <view class="name">
<view class="text">记录宠物</view>
<picker mode="selector" :range="petList" range-key="name" @change="handleList">
<view class="uni-input">{{petList[index].name?petList[index].name:'请选择宠物'}}
<icon class="iconfont icon-shouqi-xi"></icon>
</view>
</picker>
</view> -->
<view class="name">
<view class="text">记录时间</view>
<view class="example-body">
<uni-datetime-picker type="datetime" v-model="recordTime" @change="changeLog" :border="false"
:clear-icon='false' :hide-second='true' />
</view>
</view>
</view>
<view class="item">
<view class="ji">小记</view>
<textarea v-model="content" placeholder="说点什么吧" name="content" maxlength="200" />
<view class="length">{{content.length}}/200</view>
</view>
<view class="btn" @click="handleCloseClick">保存</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
index: -1,
petId: "",
content: '',
recordTime: ""
}
},
computed: {
...mapState(["petInfo", "petList"]),
start() {
return this.$tools.getTime()
},
},
mounted() {
this.recordTime = this.$tools.getTime()
},
methods: {
//
handleList(e) {
this.index = e.target.value
this.petId = this.petList[e.target.value].id
},
//
changeLog(e) {
this.recordTime = e
},
//
handleCloseClick() {
let that = this
// if (!that.petId) {
// that.$tools.msg("")
// return
// }
if (!that.recordTime) {
that.$tools.msg("请选择记录时间")
return
}
that.$model.getNotepadSubmit({
petId: uni.getStorageSync('petid'),
content: that.content,
recordTime: that.recordTime,
}).then((res) => {
if (res.code != 0) false
that.$tools.msg("记录成功!")
uni.redirectTo({
url: "/pages/notepad/notepad"
})
})
},
}
}
</script>
<style lang="scss" scoped>
.btn {
margin-top: 25px;
}
/deep/.example-body {
picker {
text-align: center !important;
}
}
</style>

View File

@ -0,0 +1,87 @@
<template>
<view class="content">
<view class="add" @click="handleAdd" v-if="token">+新增记事</view>
<view v-if="list.length" class="tipsList">
<view class="tips" v-for="(ite,ind) in list" :key="ind">
<view class="title">{{ite.recordtime}}</view>
<uni-swipe-action>
<uni-swipe-action-item :right-options="ite.options">
<view class="list">
<icon class="t-icon t-icon-a-ziyuan265"></icon>
<view class="info">
<view class="time">{{petInfo.name}}</view>
<text>记事内容</text>
<text>{{ite.content}}</text>
</view>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<view class="endtext" v-if="!lastPage || page >= lastPage"> 到底了看看别的吧 </view>
</view>
<view class="nolist mt-15" v-if="!lastPage">
<image src="../../static/none.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
token: "",
list: [],
page: 1,
lastPage: 0,
}
},
computed: {
...mapState(["petList", "petInfo"]),
},
onShow() {
let that = this
that.page = 1
that.list = []
},
methods: {}
}
</script>
<style lang="scss" scoped>
.add {
width: 100%;
text-align: center;
background: #fff;
height: 45px;
line-height: 45px;
border-radius: 5px;
font-weight: bold;
font-size: 16px;
}
.content {
padding: 15px
}
.info {
// height: 50px;
}
text {
margin-top: 3px !important;
width: auto !important;
font-size: 13px;
}
.nolist {
text {
margin: -15px auto 15px !important;
width: 100% !important;
}
}
</style>

155
pageTwo/score/history.vue Normal file
View File

@ -0,0 +1,155 @@
<template>
<view class="common">
<!-- 头部 -->
<headerIndex :isArea="false"></headerIndex>
<!-- -->
<view class="history" v-if="ranklist.length">
<view class="list" v-for="(item, index) in ranklist" :key="index" @click="clickItemMethod(item.id)">
<view class="data">
<icon class="t-icon t-icon-shijian-mianxing-0"></icon>
{{item.create_time}}
</view>
<view class="item">
<view class="time">
地区{{item.address}}
</view>
<view class="number">
{{item.score}}
<uni-icons type="right"></uni-icons>
</view>
</view>
</view>
<view class="endtext" v-if="!lastPage || page >= lastPage"> 到底了看看别的吧 </view>
</view>
<view class="nolist" v-if="!lastPage">
<image src="../../static/none.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script>
import headerIndex from "@/element/headerIndex.vue";
import {
mapState
} from "vuex";
export default {
computed: {
...mapState(['user', "appTheme"]),
},
data() {
return {
page: 1,
ranklist: [],
lastPage: "",
}
},
components: {
headerIndex
},
computed: {
...mapState(["user"]),
userId() {
return this.user.id
}
},
onLoad() {
let that = this
that.page = 1
that.getList(1)
},
watch: {
userId() {
let that = this
that.page = 1
that.ranklist = []
that.getList(1)
console.log("user变了")
},
},
onReachBottom() {
let that = this
console.log("onReachBottom", this.lastPage)
if (!this.lastPage || this.page >= this.lastPage) {
uni.showToast({
title: '没有更多数据!',
icon: 'none'
})
return
}
this.page++
this.getList(this.page)
},
methods: {
clickItemMethod(id) {
uni.navigateTo({
url: "/pageTwo/score/report?id=" + id
})
},
getList(page) {
let that = this
that.$model.getSportshistory({
aud_id: uni.getStorageSync('userid'),
page: page,
}).then((res) => {
console.log("历史记录", res)
if (res.code != 0) return
this.ranklist = this.ranklist.concat(res.data.rows)
this.lastPage = res.data.totalpage
})
},
}
}
</script>
<style scoped="scoped" lang="scss">
.common {
width: 100%;
min-height: 100.5vh; //
overflow-y: scroll;
background-color: #f7f7f7;
}
.history {
width: calc(100% - 30px);
height: auto;
margin: 15px 15px 0;
padding-bottom: 40px;
.list {
width: 100%;
border-radius: 10px;
margin-bottom: 12px;
.data {
width: 100%;
justify-content: center;
margin-bottom: 8px;
display: flex;
align-items: center;
font-size: 36rpx;
icon {
width: 40rpx;
height: 40rpx;
margin-right: 8px;
}
}
.item {
width: calc(100% - 40rpx);
display: flex;
justify-content: space-between;
background: #fff;
font-weight: 700;
line-height: 50rpx;
padding: 10px;
font-size: 36rpx !important;
}
.time {
font-size: 32rpx;
font-weight: 500;
}
}
}
</style>

89
pageTwo/score/report.vue Normal file
View File

@ -0,0 +1,89 @@
<template>
<view class="content">
<view class="time text_c bold">{{create_time}}</view>
<!-- 估分 -->
<view class="box">
<view class="title bold">本次估分成绩为</view>
<view class="charts">
<qiun-data-charts type="arcbar" :chartData="chartData" :Height="140" :Width="140"/>
<view class="name">{{score}}</view>
</view>
<view class="title bold" v-if="Max_score">该地区体育总成绩为:{{Max_score}}</view>
</view>
<!-- -->
<view v-for="(item,index) in selectllist">
<view class="titleName bold mt-15 ml-15 size16">{{item.name}}</view>
<view class="indexCarList">
<view class="card" v-for="(ite,ind) in item.list">
<view class="title">
<view class="name">{{ite.name}}</view>
</view>
<view class="item3" v-for="(it,id) in ite.list" v-if="ite.list.length>1">
<view class="name">{{it.name}}</view>
<view class="weight">
<view class="input">{{it.value?it.value:'-'}}</view>
<view class="cblue bold">{{it.proportion_value?it.proportion_value:'-'}}</view>
<view class="cblue bold">{{it.total_score?it.total_score:'-'}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue';
export default {
data() {
return {
chartData: {
series: [{
name: "正确率",
color: "#4687F9",
data: 0.8
}]
},
score: 0,
Max_score: 0,
create_time: "",
selectllist: []
}
},
components: {
qiunDataCharts
},
onLoad(options) {
let that = this
that.getList(options.id)
},
methods: {
getList(id) {
let that = this
that.$model.getSportshistorydetail({
id: Number(id),
}).then((res) => {
console.log("历史记录详情", res)
if (res.code != 0) return
that.selectllist = res.data.list
that.score = Number(res.data.score)
that.Max_score = res.data.max_score
that.create_time = res.data.create_time
that.chartData.series[0].data = Number(res.data.score) / Number(that.Max_score)
})
},
}
}
</script>
<style scoped lang="scss">
@import "@/scss/report.scss";
.content {
min-height: 100vh;
padding-top: 15px;
padding-bottom: 15px;
background-color: #f7f7f7;
}
</style>

209
pageTwo/setting/email.vue Normal file
View File

@ -0,0 +1,209 @@
<template>
<view class="content">
<view class="login">
<view class="editem">
<view class="item">
<view class="text">邮箱</view>
<view class="input">
<input v-model="phone" placeholder="请输入邮箱"/>
</view>
</view>
<view class="item ">
<view class="text">验证码</view>
<view class="input yanzhengma">
<input class="uni-input" v-model="code" />
<button class="code" type="none" @click="handleCode" v-model="code"
:disabled="disabled">{{second<60 ? second+'S后重发':$t("login.sendcode")}}
</button>
</view>
</view>
</view>
<view class="btnlogin" @click="handleTelLogin">确认</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
phone: "",
code: "",
disabled: false,
second: 60,
}
},
methods: {
//
handleTelLogin() {
let that = this
if (!(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(that.phone))) {
that.$tools.msg("请输入正确的邮箱")
return
}
if (!that.code) {
that.$tools.msg("请填写验证码")
return
}
that.$model.getAccountMsg({
data: that.phone,
code: that.code,
}).then(res => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
} else {
that.$tools.msg("设置成功!")
that.$store.commit('changeAccountNumber', {
my_email: that.phone
})
uni.redirectTo({
url: "/pageTwo/setting/setting"
})
}
}).catch(err => {})
},
//
handleCode() {
let that = this
if (!that.phone) {
that.$tools.msg("请输入邮箱")
return
}
if (!(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(that.phone))) {
that.$tools.msg("请输入正确的邮箱")
return
}
//
that.$model.getSendCode({
data: that.phone,
// type: that.type
}).then(res => {
console.log(res)
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.disabled = true
let interval = setInterval(() => {
--that.second
}, 1000)
setTimeout(() => {
clearInterval(interval)
that.disabled = false
that.second = 60
}, 60000)
}).catch(err => {})
},
}
}
</script>
<style scoped lang="scss">
.content {
width: 100%;
height: 100vh;
}
.login {
width: calc(100% - 30px);
height: auto;
background: #fff;
border-radius: 10px;
padding: 15px;
background-color: #fff;
z-index: 99;
.title {
text-align: left;
color: #333;
font-size: 40rpx;
font-weight: bold;
margin-bottom: 15px;
}
.editem {
position: relative;
display: flex;
align-items: center;
font-size: 32rpx;
justify-content: space-between;
flex-wrap: wrap;
.item {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
.text {
width: 80px;
height: 40px;
line-height: 40px;
font-size: 32rpx;
}
.input {
width: calc(100% - 100px);
height: 35px;
line-height: 35px;
display: flex;
position: relative;
border: #dfdfdf 1px solid;
border-radius: 5px;
padding: 0 10px;
background-color: #f7f7f7;
}
input {
height: 40px;
line-height: 40px;
position: absolute;
left: 10px;
right: 0px;
z-index: 88;
font-size: 32rpx;
}
.yanzhengma {
input {
right: 120px;
font-size: 32rpx;
}
}
}
.code {
width: 110px;
background: #dfdfdf;
font-size: 32rpx;
margin: 0;
line-height: 40px;
border-radius: 5px;
text-align: center;
position: absolute;
right: 0px;
top: 0px;
bottom: 0;
z-index: 99;
}
}
.btnlogin {
width: 100%;
margin: 15px 0;
height: 42px;
line-height: 42px;
background: $btncolor;
font-weight: 700;
border-radius: 15px;
text-align: center;
color: #fff !important;
}
}
</style>

View File

@ -0,0 +1,139 @@
<template>
<view class="content">
<view class="login">
<view class="editem">
<view class="item">
<view class="text">密码</view>
<view class="input">
<input class="uni-input" v-model="password" placeholder="请输入密码"/>
</view>
</view>
<view class="item">
<view class="text">确认密码</view>
<view class="input">
<input class="uni-input" v-model="password2" placeholder="请输入确认密码"/>
</view>
</view>
</view>
<view class="btnlogin" @click="handleTelLogin">确认</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
password: "",
password2: "",
}
},
onLoad() {},
methods: {
//
handleTelLogin() {
let that = this
if (!that.password) {
that.$tools.msg("请填写密码")
return
}
if (!that.password2) {
that.$tools.msg("请确认密码")
return
}
if (that.password2 != that.password) {
that.$tools.msg("请确认两次密码填写一致")
return
}
that.$model.getAccountPassword({
password: that.password,
c_password: that.password2,
}).then(res => {
console.log("注册", res)
if (res.code != 0) {
that.$tools.msg(res.msg)
} else {
that.$tools.msg("密码设置成功")
uni.navigateBack()
}
}).catch(err => {})
},
}
}
</script>
<style scoped lang="scss">
.content {
width: 100%;
height: 100vh;
}
.login {
width: calc(100% - 30px);
height: auto;
background: #fff;
border-radius: 10px;
padding: 15px;
background-color: #fff;
z-index: 99;
.editem {
position: relative;
display: flex;
align-items: center;
font-size:28rpx;
justify-content: space-between;
flex-wrap: wrap;
.item {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
.text {
width: 80px;
height: 40px;
line-height: 40px;
font-size: 32rpx;
}
.input {
width: calc(100% - 100px);
height: 35px;
line-height: 35px;
display: flex;
position: relative;
border: #dfdfdf 1px solid;
border-radius: 5px;
padding: 0 10px;
background-color: #f7f7f7;
}
input {
height: 40px;
line-height: 40px;
position: absolute;
left: 10px;
right: 0px;
z-index: 88;
font-size: 28rpx;
}
}
}
.btnlogin {
width: 100%;
margin: 15px 0;
height: 42px;
line-height: 42px;
background: $btncolor;
font-weight: 700;
border-radius: 15px;
text-align: center;
color: #fff !important;
}
}
</style>

209
pageTwo/setting/phone.vue Normal file
View File

@ -0,0 +1,209 @@
<template>
<view class="content">
<view class="login">
<view class="editem">
<view class="item">
<view class="text">手机号</view>
<view class="input">
<input v-model="phone" placeholder="请输入手机号" />
</view>
</view>
<view class="item ">
<view class="text">验证码</view>
<view class="input yanzhengma">
<input class="uni-input" v-model="code" />
<button class="code" type="none" @click="handleCode" v-model="code"
:disabled="disabled">{{second<60 ? second+'S后重发':$t("login.sendcode")}}
</button>
</view>
</view>
</view>
<view class="btnlogin" @click="handleTelLogin">确认</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
phone: "",
code: "",
disabled: false,
second: 60,
}
},
methods: {
//
handleTelLogin() {
let that = this
if (!phoneType && !(/^1[3456789]\d{9}$/.test(that.phone))) {
that.$tools.msg("请输入正确的手机号")
return
}
if (!that.code) {
that.$tools.msg("请填写验证码")
return
}
that.$model.getAccountMsg({
data: that.phone,
code: that.code,
}).then(res => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
} else {
that.$tools.msg("设置成功!")
that.$store.commit('changeAccountNumber', {
my_tel: that.phone
})
uni.redirectTo({
url: "/pageTwo/setting/setting"
})
}
}).catch(err => {})
},
//
handleCode() {
let that = this
if (!that.phone) {
that.$tools.msg("请输入手机号")
return
}
if (!phoneType && !(/^1[3456789]\d{9}$/.test(that.phone))) {
that.$tools.msg("请输入正确的手机号")
return
}
//
that.$model.getSendCode({
data: that.phone,
// type: that.type
}).then(res => {
console.log(res)
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.disabled = true
let interval = setInterval(() => {
--that.second
}, 1000)
setTimeout(() => {
clearInterval(interval)
that.disabled = false
that.second = 60
}, 60000)
}).catch(err => {})
},
}
}
</script>
<style scoped lang="scss">
.content {
width: 100%;
height: 100vh;
}
.login {
width: calc(100% - 30px);
height: auto;
background: #fff;
border-radius: 10px;
padding: 15px;
background-color: #fff;
z-index: 99;
.title {
text-align: left;
color: #333;
font-size:40rpx;
font-weight: bold;
margin-bottom: 15px;
}
.editem {
position: relative;
display: flex;
align-items: center;
font-size:28rpx;
justify-content: space-between;
flex-wrap: wrap;
.item {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
.text {
width: 80px;
height: 40px;
line-height: 40px;
font-size:28rpx;
}
.input {
width: calc(100% - 100px);
height: 35px;
line-height: 35px;
display: flex;
position: relative;
border: #dfdfdf 1px solid;
border-radius: 5px;
padding: 0 10px;
background-color: #f7f7f7;
}
input {
height: 40px;
line-height: 40px;
position: absolute;
left: 10px;
right: 0px;
z-index: 88;
font-size:28rpx;
}
.yanzhengma {
input {
right: 120px;
font-size: 32rpx;
}
}
}
.code {
width: 110px;
background: #dfdfdf;
font-size: 32rpx;
margin: 0;
line-height: 40px;
border-radius: 5px;
text-align: center;
position: absolute;
right: 0px;
top: 0px;
bottom: 0;
z-index: 99;
}
}
.btnlogin {
width: 100%;
margin: 15px 0;
height: 42px;
line-height: 42px;
background: $btncolor;
font-weight: 700;
border-radius: 15px;
text-align: center;
color: #fff !important;
}
}
</style>

159
pageTwo/setting/setting.vue Normal file
View File

@ -0,0 +1,159 @@
<template>
<view class="content">
<view class="caritem">
<view class="text">头像</view>
<image :src="user.head_pic" class="image"></image>
</view>
<view class="caritem">
<view class="text">昵称</view>
<view class="text_r">
<text v-if="!isEdit">{{user.nickname}}</text>
<input v-else type="text" v-model='nickname' @blur="handleBlur" />
<uni-icons type="compose" color="#FEC407" @click="isEdit=true" class="ml-10" size="22"></uni-icons>
</view>
</view>
<view class="caritem" @click="navTo('/pageTwo/setting/phone')">
<view class="text">手机号</view>
<view class="text_r">
<text>{{user.my_tel}}</text>
<uni-icons type="right"></uni-icons>
</view>
</view>
<view class="caritem" @click="navTo('/pageTwo/setting/email')">
<view class="text">邮箱</view>
<view class="text_r">
<text>{{user.my_email}}</text>
<uni-icons type="right"></uni-icons>
</view>
</view>
<view class="caritem" @click="navTo('/pageTwo/setting/password')">
<view class="text">设置密码</view>
<uni-icons type="right"></uni-icons>
</view>
<view class="btn mb-15" @click="handleOutLogin">删除账号</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
export default {
data() {
return {
isEdit: false,
headimg: null,
nickname: ""
};
},
computed: {
...mapState(["accountNumber"]),
user() {
return this.accountNumber
}
},
methods: {
handleOutLogin() {
let that = this
uni.showModal({
title: '友情提示',
confirmText: '删除',
content: '删除成功后,该账号的所有关联信息将被清空且无法找回,是否删除?',
success: function(res) {
if (res.confirm) {
that.$model.getdeleteAccount({}).then((res) => {
if (res.code != 0) return
that.$tools.msg("删除成功!");
uni.setStorageSync('token', null)
uni.setStorageSync('aan_id', null)
uni.clearStorageSync()
setTimeout(() => {
uni.reLaunch({
url: "/pageTwo/login/login"
})
}, 3000);
})
} else if (res.cancel) {
that.$tools.msg("您已取消操作!");
}
},
})
},
//
handleBlur() {
let that = this
return that.$model.getAccountNickname({
nickname: that.nickname,
}).then(res => {
if (res.code != 0) return
that.user.nickname = that.nickname
that.$store.commit('changeAccountNumber', {
nickname: that.nickname
})
that.isEdit = false
})
},
navTo(url) {
uni.navigateTo({
url
})
},
}
}
</script>
<style lang="scss" scoped>
.content {
background-color: #F3F4F6;
padding: 15px;
min-height: 100vh;
font-size: 36rpx;
}
.image {
width: 40px;
height: 40px;
border-radius: 50%;
}
.text_r {
width: 70%;
display: flex;
align-items: center;
justify-content: flex-end;
text {
width: calc(100% - 30px);
display: inline-block;
}
input {
width: 80%;
border-bottom: 1px solid #dfdfdf;
}
}
.btn {
width: auto;
background: #999;
margin: 50px 15px 0 15px;
}
.caritem {
height: 50px;
line-height: 50px;
background-color: #fff;
border-radius: 10px;
padding: 0 10px;
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: space-between;
.uni-icons {
width: 30px;
text-align: right;
}
}
</style>

BIN
pageTwo/static/100.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/1000.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/150.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/200.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/250.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/300.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/350.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/400.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/450.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/50.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/500.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/550.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/600.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/650.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/700.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/750.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/800.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/850.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/900.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/950.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/HC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
pageTwo/static/PCL.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
pageTwo/static/Start.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/duan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
pageTwo/static/flight.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/number.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/t01.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
pageTwo/static/time.mp3 Normal file

Binary file not shown.

BIN
pageTwo/static/xu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,21 @@
<template>
<web-view :src="webviewUrl"></web-view>
</template>
<script>
export default {
data() {
return {
webviewUrl: ''
};
},
// URL
onLoad(options) {
let that = this
let token = uni.getStorageSync('token')
let url = options.url + '?token=' + token + '&id=' + options.id
that.webviewUrl = decodeURIComponent(url);
console.log("11111", options, url, this.webviewUrl)
}
}
</script>

View File

@ -1,17 +1,400 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"path": "pages/home/home",
"style": {
"navigationBarTitleText": "uni-app"
"navigationBarTitleText": "",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/skiping/skip",
"style": {
"navigationBarTitleText": "跳绳数据",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/skiping/charts",
"style": {
"navigationBarTitleText": "运动曲线",
"enablePullDownRefresh": false
}
},
{
"path": "pages/lunging/vitalcapacity",
"style": {
"navigationBarTitleText": "肺活量数据",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50,
"navigationBarBackgroundColor": "#000000",
"backgroundColor": "#000000"
}
},
{
"path": "pages/lunging/charts",
"style": {
"navigationBarTitleText": "运动曲线",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/me",
"style": {
"navigationBarTitleText": "我的",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/score/score",
"style": {
"navigationBarTitleText": "分数评估",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/PublicCards/PublicCards",
"style": {
"navigationBarTitleText": "对比详情"
}
},
{
"path": "pages/body/body",
"style": {
"navigationBarTitleText": "身体数据",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/zixun/list",
"style": {
"navigationBarTitleText": ""
}
}
],
"subPackages": [{
"root": "pageTwo",
"pages": [{
"path": "history/history",
"style": {
"navigationBarTitleText": "历史记录",
"enablePullDownRefresh": false
}
},
{
"path": "history/historyDetail",
"style": {
"navigationBarTitleText": "记录详情",
"enablePullDownRefresh": false
}
},
{
"path": "compk/contrast",
"style": {
"navigationBarTitleText": "数据对比",
"enablePullDownRefresh": false
}
},
{
"path": "compk/pkdetail",
"style": {
"navigationBarTitleText": "对比详情",
"enablePullDownRefresh": false
}
}, {
"path": "cardList/card",
"style": {
"navigationBarTitleText": "卡片设置",
"enablePullDownRefresh": false
}
},
{
"path": "business/business",
"style": {
"navigationBarTitleText": "设备管理",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
}, {
"path": "business/addDevice",
"style": {
"navigationBarTitleText": "设备列表",
"enablePullDownRefresh": false
}
},
{
"path": "business/search",
"style": {
"navigationBarTitleText": "搜索设备",
"enablePullDownRefresh": false
}
},
{
"path": "score/history",
"style": {
"navigationBarTitleText": "估分历史",
"enablePullDownRefresh": false
}
}, {
"path": "score/report",
"style": {
"navigationBarTitleText": "估分报告",
"enablePullDownRefresh": false
}
},
{
"path": "my/manage",
"style": {
"navigationBarTitleText": "成员管理",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "message/list",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "my/userInfo",
"style": {
"navigationBarTitleText": "资料"
}
},
{
"path": "login/forgetPassword",
"style": {
"navigationBarTitleText": "密码",
"enablePullDownRefresh": false
}
},
{
"path": "login/login",
"style": {
"navigationBarTitleText": "登录",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "my/about",
"style": {
"navigationBarTitleText": "关于我们",
"enablePullDownRefresh": false
}
},
{
"path": "setting/setting",
"style": {
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false
}
},
{
"path": "setting/password",
"style": {
"navigationBarTitleText": "修改密码",
"enablePullDownRefresh": false
}
},
{
"path": "setting/email",
"style": {
"navigationBarTitleText": "绑定邮箱",
"enablePullDownRefresh": false
}
},
{
"path": "setting/phone",
"style": {
"navigationBarTitleText": "绑定手机号",
"enablePullDownRefresh": false
}
},
{
"path": "devices/search",
"style": {
"navigationBarTitleText": "蓝牙搜索",
"enablePullDownRefresh": false
}
},
{
"path": "devices/G02",
"style": {
"navigationBarTitleText": "测量",
"enablePullDownRefresh": false
}
},
{
"path": "devices/PCL",
"style": {
"navigationBarTitleText": "测量",
"enablePullDownRefresh": false
}
}, {
"path": "devices/PCV02",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "devices/PCT01",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path" : "devices/B20",
"style" :
{
"navigationBarTitleText" : "",
"enablePullDownRefresh": false
}
},
{
"path" : "devices/PCL22",
"style" :
{
"navigationBarTitleText" : "",
"enablePullDownRefresh": false
}
},
{
"path" : "devices/PCL22S",
"style" :
{
"navigationBarTitleText" : "",
"enablePullDownRefresh": false
}
},
{
"path": "notepad/notepad",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "notepad/addNotepad",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "PublicCards/charts",
"style": {
"navigationBarTitleText": "运动曲线"
}
},
{
"path": "PublicCards/history",
"style": {
"navigationBarTitleText": "历史记录"
}
},
{
"path": "PublicCards/contrast",
"style": {
"navigationBarTitleText": "数据对比"
}
},
{
"path": "PublicCards/pkdetail",
"style": {
"navigationBarTitleText": "对比详情"
}
},
{
"path": "home/inheritHeighet",
"style": {
"navigationBarTitleText": "身高预测"
}
},
{
"path": "home/bmi",
"style": {
"navigationBarTitleText": "BMI测评"
}
},
{
"path": "webview/webview",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
]
}],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
"navigationBarTextStyle": "white",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#37cc92",
"backgroundColor": "#fff"
},
//
"tabBar": {
"color": "#333",
"fontSize": "14px",
"selectedColor": "#37cc92",
"backgroundColor": "#fff",
"list": [{
"pagePath": "pages/home/home",
"iconPath": "static/shou.png",
"selectedIconPath": "static/shou2.png",
"text": "记录"
},
{
"pagePath": "pages/zixun/list",
"iconPath": "static/ping.png",
"selectedIconPath": "static/ping2.png",
"text": "资讯"
},
{
"pagePath": "pages/my/me",
"iconPath": "static/wo.png",
"selectedIconPath": "static/wo2.png",
"text": "我的"
}
]
},
"uniIdRouter": {}
}
}

View File

@ -0,0 +1,422 @@
<template>
<view class="content ">
<view class="tabbar">
<scroll-view class="scroll-menu" scroll-x="true" style="white-space: nowrap;">
<view v-for="(item,index) in labelList" :class="[active==index?'active':'']"
@click="handleActive(item,index)">
<text>{{item}}</text>
</view>
</scroll-view>
</view>
<!-- -->
<view class="desc">
<view class="statuevue">
<view class="bi">
<view class="peobox" :style="'left:'+Number(offset)+'%'">
<view class="xx"></view>
</view>
<view class="item" v-for="(ite,ind) in lineList" :key="ind" :style="{backgroundColor:ite.color}">
<view class="span1">{{ite.text}}</view>
<view class="span" v-if="ind<lineList.length-1">{{ite.max_val}}</view>
</view>
</view>
</view>
</view>
<!-- -->
<view v-for="(ite,ind) in label_data" v-if="active == ind">
<view class="info">
<view class="table">
<text class="time">{{ite.record_time}}</text>
<text class="name2">训练成绩为</text>
</view>
<view class="left">
<view class="left_view">
<view class="title">{{ite.this_time_title}}:</view>
<view class="val">
<text class="yello"></text>
{{ite.this_time_value?ite.this_time_value:'-'}}
</view>
</view>
<view class="left_view">
<view class="title">{{ite.today_time_title}}:</view>
<view class="val">
<text class="yello"></text>
{{ite.today_time_value?ite.today_time_value:'-'}}
</view>
</view>
<view class="left_view">
<view class="title"></view>
<view class="val">
<text class="blues yello"></text>
{{ite.today_times?ite.today_times:'-'}}
</view>
</view>
<view class="left_view">
<view class="title">{{ite.all_time_title}}:</view>
<view class="val">
<text class="yello"></text>
{{ite.all_time_value?ite.all_time_value:'-'}}
</view>
</view>
<view class="left_view">
<view class="title"></view>
<view class="val">
<text class="blues yello"></text>
{{ite.all_times?ite.all_times:'-'}}
</view>
</view>
</view>
<view class="right">
<view class="charts">
<qiun-data-charts type="arcbar" :chartData="chartData" :Height="130" :Width="130" :canvas2d="true"/>
<view class="name">{{ite.score?ite.score:'-'}}</view>
</view>
<view class="standard" v-if="ite.standard">
<text :style="{backgroundColor:ite.color}">{{ite.standard}}</text>
</view>
<view v-if="ite.max_score" class="size12 c999"> 总成绩为{{ite.max_score}}</view>
</view>
</view>
<!-- 说明 -->
<view class="info describe" v-if="ite.describe">
{{ite.describe}}
</view>
</view>
<!-- -->
<view class="gridList">
<view class="data">
<view class="item" @click="navTo('/pageTwo/PublicCards/charts?acd_id='+acd_id)">
<view class="image">
<image src="@/static/charts.png"></image>
</view>
<view class="name">运动曲线</view>
</view>
<view class="item" @click="navTo('/pageTwo/PublicCards/history?acd_id='+acd_id)">
<view class="image">
<image src="@/static/add.png"></image>
</view>
<view class="name">历史记录</view>
</view>
<view class="item" @click="navTo('/pageTwo/PublicCards/contrast?acd_id='+acd_id)">
<view class="image">
<image src="@/static/pk.png"></image>
</view>
<view class="name">数据对比</view>
</view>
<view class="item" @click="$store.commit('changePublicAdd',true)">
<view class="image">
<image src="@/static/history.png"></image>
</view>
<view class="name">添加记录</view>
</view>
</view>
</view>
<!-- 手动记录 -->
<publicAdd :rtype='acd_id' :active="active"></publicAdd>
</view>
</template>
<script>
import {
mapState
} from "vuex";
import publicAdd from '@/element/manuallyAdd/publicAdd.vue';
import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue';
export default {
data() {
return {
active: 0,
acd_id: null,
lineList: [],
label_data: [],
offset: 0,
labelName: "",
chartData: {
series: [{
name: "正确率",
color: "#4687F9",
data: 0
}]
},
}
},
components: {
publicAdd,
qiunDataCharts
},
computed: {
...mapState(["PublicContent"]),
labelList() {
let that = this
if (that.PublicContent) {
that.labelName = that.PublicContent.label_list[that.active]
that.lineList = that.PublicContent.line_list
that.label_data = that.PublicContent.label_data
that.offset = that.PublicContent.label_data[that.active].offset
that.chartData.series[0].data = that.PublicContent.label_data[that.active].score.split('分')[0]/that.PublicContent.label_data[that.active].max_score
}
return that.PublicContent ? that.PublicContent.label_list : []
},
},
onLoad(options) {
let that = this
that.acd_id = options.acd_id
that.$store.dispatch("getPublicContent", {
acd_id: that.acd_id,
aud_id: uni.getStorageSync('userid')
})
},
methods: {
handleActive(ite, ind) {
let that = this
that.active = ind
that.labelName = ite
that.offset = that.label_data[ind].offset
that.chartData.series[0].data = Number(that.label_data[ind].offset) / 100
},
//
reload() {
let that = this
console.log('返回历史页', that.acd_id)
this.$nextTick(() => {
that.$store.dispatch("getPublicContent", {
acd_id: that.acd_id,
aud_id: uni.getStorageSync('userid')
})
})
},
navTo(url) {
uni.navigateTo({
url: url
})
},
}
}
</script>
<style scoped lang="scss">
.content {
width: calc(100% - 30px);
min-height: calc(100vh - 80px);
padding: 65px 15px 15px;
background-color: #f7f7f7;
}
.tabbar {
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
justify-content: space-between;
border-bottom: 1px solid #f7f7f7;
box-shadow: 0px 1px 5px 2px #dfe2e1fc;
background-color: #fff;
.scroll-menu {
width: 100%;
white-space: nowrap;
view {
height: 55px;
line-height: 55px;
display: inline-block;
min-width: 100px;
margin: 0 10px;
text-align: center;
}
}
.active {
color: $maincolor;
font-weight: bold;
border-bottom: 2px solid $maincolor;
}
}
.desc {
padding: 15px;
text-align: left;
width: calc(100%-20px);
height: auto;
border-radius: 5px;
font-size: 30rpx;
color: #999;
margin-top: 15px;
background: #fff;
.statuevue {
height: 35px;
position: relative;
width: 100% !important;
margin: 20px auto 10px;
.bi {
display: flex;
justify-content: space-between;
width: auto;
padding-top: 10px;
.peobox {
position: absolute;
right: 0;
top: -1px;
.xx {
width: 5px;
height: 5px;
border-radius: 50%;
background: #fff;
position: absolute;
z-index: 9;
border: 2px solid #1b2086;
top: 9px;
}
}
}
.item {
position: relative;
margin: 0;
flex: 1;
height: 5px;
color: #666;
font-size: 30rpx;
.span1 {
width: 100%;
text-align: center;
position: absolute;
top: -23px;
}
.span {
margin-top: 8px;
position: absolute;
right: -8px;
}
}
}
}
.describe {
color: #666;
font-size: 28rpx;
line-height: 25px;
}
.info {
background-color: #fff;
padding: 15px;
margin-top: 15px;
border-radius: 5px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.table {
width: 100%;
display: flex;
flex-wrap: wrap;
.name2 {
width: 260rpx;
text-align: center;
font-weight: bold;
font-size: 36rpx;
}
.time {
width: calc(100% - 260rpx);
color: #999;
font-size: 32rpx;
margin-bottom: 5px;
display: inline-block;
}
}
.left {
width: calc(100% - 280rpx);
display: flex;
flex-wrap: wrap;
.left_view {
width: 100%;
display: flex;
align-items: center;
}
.title {
width: 80px;
font-weight: bold;
margin-right: 10px;
}
}
.right {
width: 260rpx;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
.charts {
width: 260upx;
height: 260upx;
margin: 10px 0;
position: relative;
display: flex;
align-items: center;
justify-content: center;
z-index: 9;
.name {
width: 100%;
text-align: center;
font-size: 56rpx;
color: #4687F9;
position: absolute;
}
}
.title {
width: 100%;
text-align: center;
}
}
}
.standard {
width: 100%;
text-align: center;
margin-top: 0px;
margin-bottom: 8px;
text {
width: 100px;
color: #fff;
font-size: 14px;
padding: 2px 10px;
border-radius: 5px;
}
}
.yello {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
margin-right: 5px;
background-color: $btncolor;
}
.blues {
background-color: $maincolor;
}
.gridList {
margin: 0;
}
</style>

236
pages/body/body.vue Normal file
View File

@ -0,0 +1,236 @@
<template>
<view class="content">
<!-- tabbar -->
<!-- 曲线 -->
<view class="charts">
<view class="TrendPage">
<!-- 时间选择 -->
<view class="boxTime">
<view class="one">
<picker mode="date" :end="endDate" @change="handStartTimeH" :fields="fields"
:value="startTime?startTime:startDate">
<view class="uni-input mr-10">{{startTime?startTime:startDate}}
<icon class="iconfont icon-arrow-down-bold"></icon>
</view>
</picker>
<view class="center">~</view>
<picker mode="date" :end="endDate" @change="handEndTimeH" :fields="fields"
:value="endTime?endTime:endDate">
<view class="uni-input mr-10">{{endTime?endTime:endDate}}
<icon class="iconfont icon-arrow-down-bold"></icon>
</view>
</picker>
</view>
</view>
<!-- 曲线图 -->
<view class="box" v-if="weightList.length">
<view class="listC">
<view :class="{active2: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="handTrue">
<qiunDataCharts type="area" :chartData="lineData" :canvas2d="true" canvasId="charts09"
:animation="false" :Width="340" :Height="250"
:opts="{enableScroll:true,xAxis:{scrollShow:false,itemCount:3}}" :ontouch="true" />
</view>
</view>
</view>
<view class="box" v-else>
<view class="nolist">
<image src="../../static/none.png"></image>
<text>暂无数据</text>
</view>
</view>
</view>
<!-- 目标-->
<view class="gridList">
<view class="data">
<view class="item" @click="handleClick(1)">
<view class="val">
{{userInfo.target_current?userInfo.target_current.target_weight:0}}<text>kg</text>
</view>
<view class="name">目标体重<uni-icons class="iconfont icon-bianji" color="#FEC407"></uni-icons>
</view>
</view>
<view class="item">
<view class="val">
{{userInfo.target_current?Math.abs(userInfo.target_current.cumulative_weight):0}}<text>kg</text>
</view>
<view class="name" v-if="Number(userInfo.target_current.cumulative_weight)>0">累计增重</view>
<view class="name" v-else>累计减重</view>
</view>
<view class="item" @click="handleClick(2)">
<view class="val">
{{userInfo.target_current?userInfo.target_current.initial_weight:0}}<text>kg</text>
</view>
<view class="name">初始体重<uni-icons class="iconfont icon-bianji" color="#FEC407"></uni-icons>
</view>
</view>
<view class="item">
<view class="val">
{{userInfo.target_current?userInfo.target_current.cumulative_day:0}}<text></text>
</view>
<view class="name">减重天数</view>
</view>
</view>
</view>
<!-- 初始 -->
<firstweight :type="ind"></firstweight>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
import record from '@/element/manuallyAdd/record.vue';
import firstweight from '@/element/target/firstweight.vue';
import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
export default {
data() {
return {
fields: "",
active: 1,
acd_id: 2,
ind: 0,
active1: 0,
startTime: "",
endTime: "",
lineData: {},
handTrue: true,
}
},
computed: {
...mapState(['user', "MeasureResult", "Trend"]),
weightList() {
let that = this
that.showbox(0)
return that.Trend
},
userInfo() {
return this.MeasureResult
},
endDate() {
return this.$tools.getDate("start")
},
startDate() {
return this.$tools.GetDateStr(-90);
},
},
components: {
record,
firstweight,
qiunDataCharts,
},
onLoad(options) {
let that = this
that.acd_id = options.acd_id
that.$store.dispatch("GetBodyTrendList", {
aud_id: uni.getStorageSync('userid'),
s_time: that.startDate,
e_time: that.endDate
})
// #ifdef APP-PLUS
that.fields = "time"
// #endif
// #ifndef APP-PLUS
that.fields = "day"
// #endif
},
//
onPullDownRefresh() {
let that = this
that.$store.dispatch("GetBodyTrendList", {
aud_id: uni.getStorageSync('userid'),
s_time: that.startDate,
e_time: that.endDate
})
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000);
},
methods: {
showbox(index) {
let that = this
that.handTrue = false
that.$nextTick(function() {
that.handTrue = true
that.lineData = that.weightList.length ? that.weightList[index].line : {}
})
that.active1 = index
},
//
handStartTimeH(e) {
let that = this
if (that.endTime) {
if (Date.parse(e.detail.value) > Date.parse(that.endTime)) {
that.$tools.msg("请选择正确的时间")
return
}
} else {
if (Date.parse(e.detail.value) > Date.parse(that.endDate)) {
that.$tools.msg("请选择正确的时间")
return
}
}
that.startTime = e.detail.value
let endtime = that.endTime ? that.endTime : that.endDate
that.$store.dispatch("GetBodyTrendList", {
aud_id: that.user.id,
s_time: that.startTime,
e_time: that.endTime ? that.endTime : that.endDate
})
that.showbox(0)
},
//
handEndTimeH(e) {
let that = this
if (that.startTime) {
if (Date.parse(e.detail.value) < Date.parse(that.startTime)) {
that.$tools.msg("请选择正确的时间")
return
}
} else {
if (Date.parse(e.detail.value) < Date.parse(that.startDate)) {
that.$tools.msg("请选择正确的时间")
return
}
}
that.endTime = e.detail.value
let startTime = that.startTime ? that.startTime : that.startDate
that.$store.dispatch("GetBodyTrendList", {
aud_id: uni.getStorageSync('userid'),
s_time: startTime,
e_time: that.endTime
})
that.showbox(0)
},
handleClick(ind) {
this.ind = ind
this.$store.commit("changeFirst", true);
},
}
}
</script>
<style scoped lang="scss">
@import "@/scss/body.scss";
.content {
padding: 15px;
font-size: 32rpx;
width: calc(100% - 30px);
background-color: #F5F6FA;
min-height: 100vh;
}
.listC {
margin: 0;
width: 100%;
}
</style>

901
pages/home/home.vue Normal file
View File

@ -0,0 +1,901 @@
<template>
<view class="content indexCarList">
<!-- 头部 -->
<headerIndex :isArea="false" v-if="isShow"></headerIndex>
<!-- 蓝牙提示区 -->
<view v-if="userList.length">
<view class="bleTips" v-if="islink==0">
{{textLink}}
</view>
<view class="bleTips2 bleTips" v-else @click="openBluetoothAdapter">
{{textLink}}
</view>
</view>
<view class="notice" v-if="notices.length">
<text>公告</text>
<!-- -->
<swiper class="swiper" vertical="true" autoplay="true">
<swiper-item v-for="(item,index) in notices" :key="index" @click="$tools.NewsPtype(item)">
<view class='overflow'>{{item.title}}</view>
</swiper-item>
</swiper>
</view>
<!-- 工具区 -->
<view class="tools_l">
<view v-for="(item,index) in toollist" :key="index" class="list" @click="handleTool(index,item.path)">
<image :src="item.icon"></image>
<view class="text">{{item.title}}</view>
</view>
</view>
<!-- banner -->
<view class="f_banner" v-if="banner.length">
<swiper class="swiper" indicator-dots="true" autoplay="true">
<swiper-item v-for="(image, index) in banner" :key="index" @click="$tools.NewsPtype(image)">
<image :src="image.pic" mode="aspectFill" />
</swiper-item>
</swiper>
</view>
<!-- 身体数据 -->
<view class="report">
<view class="bold mt-10 ml-10" v-if="info&&info.top_list.length">身体报告</view>
<view class="box" v-if="info&&info.top_list.length">
<view class="time">{{info?info.record_time:''}}</view>
<view class="item2">
<view class="item2_data" :style="userInfo.stage=='婴儿'?'width:25%':'width:33%'"
v-for="(item,index) in info.top_list" @click="handleToggleTop(item,index)">
<view class="data" :class="[activeHeight==index?'activeHeight':'']">
<view class="c666 mb-5">{{item.name}}</view>
<view><text>{{item.value}}</text>{{item.unit}}</view>
</view>
</view>
<view class="myinfoPage" v-if="infoListTop">
<view class="desc">
<view v-if="infoListTop.desc" class="ming">{{infoListTop.desc}}</view>
<view :class="[infoListTop.list.length?'statuevue':'']" v-if="infoListTop.list">
<view class="bi">
<view :style="'left:'+infoListTop.offset+'%'" class="peobox">
<view class="xx"></view>
</view>
<view class="item" v-for="(ite , ind) in infoListTop.list" :key="ind"
:style="{backgroundColor:ite.color}">
<view class="span1">{{ite.text}}</view>
<view class="span" v-if="ind<infoListTop.list.length-1">{{ite.max_val}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="nolist" v-if="!info">
<image src="../../static/none.png"></image>
<text>暂无数据请手动添加~</text>
</view>
<view class="box2" v-if="info&&info.body_type_value">
<view>身体得分{{info?info.score_value:0}}</view>
<view>身体类型{{info?info.body_type_value:'无'}}</view>
</view>
<view class="bold mt-10 ml-10" v-if="info&&info.bottom_list.length">其他数据</view>
<view class="ml-10 mr-10" v-if="info&&info.bottom_list.length">
<view class="myinfoPage">
<view class="box1">
<uni-collapse accordion>
<uni-collapse-item class="list" v-for="(item,index) in info.bottom_list" :key="index">
<template v-slot:title>
<uni-list-item class="block">
<view class="name">
<icon class="t-icon iconfont" :class="'t-icon-'+item.key_name"></icon>
{{item.name}}
</view>
<view class="val" v-if="item.title=='肥胖等级'||item.title=='体型'"> - </view>
<view class="val" v-else>{{item.value?item.value:'0'}}{{item.unit}}</view>
<view class="level">
<view class="btnf"
:style="{backgroundColor:(item.standard=='异常'?'#FFF':item.color)}"
:class="[item.standard=='异常'?'btnC':'']">
{{item.standard=='异常'?'-':item.standard}}
</view>
</view>
</uni-list-item>
</template>
<view class="desc">
<view v-if="item.desc" class="ming">{{item.desc}}</view>
<view :class="[item.list.length?'statuevue':'']" v-if="item.list">
<view class="bi" v-if="item.title!='基础代谢'">
<view :style="'left:'+item.offset+'%'" class="peobox">
<view class="xx"></view>
</view>
<view class="item" v-for="(ite , ind) in item.list" :key="ind"
:style="{backgroundColor:ite.color}">
<view class="span1">{{ite.text}}</view>
<view class="span" v-if="ind<item.list.length-1">{{ite.max_val}}</view>
</view>
</view>
<view v-else>
<view class="kcalClass" v-if="item.list&&item.list.length">
标准值:{{item.list[0].max_val}}kcal
</view>
</view>
</view>
</view>
</uni-collapse-item>
</uni-collapse>
</view>
</view>
</view>
<!-- 数据参考 -->
<view class="tips c999 ml-15 mb-15" v-if="info.literature.length">
<text>*数据参考</text>
<text v-for="(item,index) in info.literature" :key="index">
{{item}}
</text>
</view>
<view class="tips2 ml-10" v-if="info.bottom_list">
<uni-icons type="info-filled" color="red"></uni-icons>
此测量数据仅供参考不可代替医学专业测试
</view>
<!-- 成长建议 -->
<view v-if="cplist.sleeplist.length||cplist.nutritionlist.length" class="ml-10 mr-10">
<view class="bold mt-10">成长建议</view>
<view class="jianyi_box">
<view class="jianyi">
<view @click="proposalnd=1" :class="{active:proposalnd==1}">
<image src="../../static/icon4.png"></image>
<text>营养</text>
</view>
<view @click="proposalnd=2" :class="{active:proposalnd==2}">
<image src="../../static/icon1.png"></image>
<text>睡眠</text>
</view>
<view @click="proposalnd=3" :class="{active:proposalnd==3}">
<image src="../../static/icon3.png"></image>
<text>运动</text>
</view>
<view @click="proposalnd=4" :class="{active:proposalnd==4}">
<image src="../../static/icon2.png"></image>
<text>情绪</text>
</view>
</view>
<view>
<view v-if="proposalnd==1&&cplist.nutritionlist.length" class="jianyi-con">
<text v-for="(item,index) in cplist.nutritionlist" :key="index">{{item}}</text>
</view>
<view v-if="proposalnd==2&&cplist.sleeplist.length" class="jianyi-con">
<text v-for="(item,index) in cplist.sleeplist" :key="index">{{item}}</text>
</view>
<view v-if="proposalnd==3&&cplist.sportlist.length" class="jianyi-con">
<text v-for="(item,index) in cplist.sportlist" :key="index">{{item}}</text>
</view>
<view v-if="proposalnd==4&&cplist.moodlist.length" class="jianyi-con">
<text v-for="(item,index) in cplist.moodlist" :key="index">{{item}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 卡片 -->
<view class="list" v-if="user">
<view class="bold mt-10 ml-10" v-if="user.card_data_list.length">卡片数据</view>
<view v-for="(item,index) in user.card_data_list">
<!-- 标题 -->
<view class="card box" @click="handlerReport(item)" :style="{'backgroundColor':item.background_color}">
<view class="boxBg">
<image :src="item.background_pic"></image>
</view>
<view class="title border">
<view class="name2">{{item.card_name}}</view>
<view class="time">
{{item.record_time}}
<uni-icons type="right" size="20" v-if="item.inside_data[0].value"></uni-icons>
</view>
</view>
<view class="target item">
<view class="bold size16 c666" v-if="item.acd_id!=2">本次数据</view>
<view class="bold size14" v-else>
<text class="size32">{{item.inside_data[1].value}}</text>
{{item.inside_data[1].unit}}
</view>
<view class="btnGroup">
<view class="blueBtn" v-if="item.acd_id==2" @click.stop
@click="$Bluetooth.handleDevicesMac(item.device_determine,item.acd_id)">蓝牙连接</view>
<view class="blueBtn" v-else-if="item.acd_id==6">蓝牙连接</view>
<view v-else></view>
<view class="orangeBtn" @click="handlerRecord(item.acd_id)" @click.stop>手动记录</view>
</view>
</view>
<!-- 内容 -->
<view class="item title"
:style="{'justifyContent':item.inside_data.length>2?'space-between':'center'}">
<view v-for="(ite,ind) in item.inside_data" :class="[item.inside_data.length>3?'item2':'']">
<view class="weight"><text>{{ite.value?ite.value:'-'}}</text>{{ite.unit}}</view>
<view class="name mt-5" v-if="item.acd_id!=8">{{ite.name}}</view>
</view>
</view>
</view>
</view>
</view>
<!-- 设置数据卡片 -->
<view class="setcard" @click="handleCard" v-if="userList.length&&user.measure_model==1">
设置数据页卡片
</view>
<!-- 弹框广告 -->
<view class="wrapper" v-if="isCoupon">
<view class="bg" @click="isCoupon=false">
<view class="edit">
<swiper class="text" autoplay="true">
<swiper-item v-for="(ite,ind) in pop" :key="ind" @click="$tools.NewsPtype(ite)">
<image :src="ite.pic" mode="aspectFill" />
<view class="bold mt-5">{{ite.title}}</view>
</swiper-item>
</swiper>
<uni-icons type="clear" @click="isCoupon=false" size="40" class="clear"></uni-icons>
</view>
</view>
</view>
<!-- <view class="nolist" @click="handleAddUser" :style="{'marginTop':isShow?'150px':'0'}">
<image src="../../static/none.png"></image>
<text>请先添加成员</text>
</view> -->
<!-- 手动 -->
<record :rtype="rtype"></record>
</view>
</template>
<script>
import {
mapState
} from "vuex";
let myTime;
import headerIndex from "@/element/headerIndex.vue"
import record from '@/element/manuallyAdd/record.vue';
import {
I18nT
} from "vue-i18n";
export default {
data() {
return {
rtype: 0,
transition: 1.6,
isShow: true,
infoListTop: {},
activeHeight: 0,
deviceName: "",
deviceId: "",
serviceId: "",
write: "",
notify: "",
isCoupon: false,
notices: [],
banner: [],
pop: [],
devicesList: [],
islink: 0, //-1
textLink: "",
proposalnd: 1,
toollist: [{
icon: '/static/q2.png',
title: '中招估分',
path: "/pages/score/score"
}, {
icon: '/static/q4.png',
title: 'BMI测评',
path: "/pageTwo/home/bmi"
},
{
icon: '/static/q6.png',
title: '遗传身高',
path: "/pageTwo/home/inheritHeighet"
},
{
icon: '/static/q1.png',
title: '智能跳绳',
path: "/pages/skiping/skip?acd_id=6"
},
{
icon: '/static/q10.png',
title: '肺活训练',
path: "/pages/lunging/vitalcapacity?acd_id=8"
},
{
icon: '/static/q8.png',
title: '历史体重',
path: "/pageTwo/history/history?acd_id=2"
},
{
icon: '/static/q3.png',
title: '减脂对比',
path: "/pageTwo/compk/contrast?acd_id=2"
},
{
icon: '/static/q5.png',
title: '曲线/目标',
path: "/pages/body/body?acd_id=2"
},
{
icon: '/static/q7.png',
title: '手动记录',
path: ""
},
{
icon: '/static/q9.png',
title: '成员管理',
path: "/pageTwo/my/manage"
},
],
unit: ""
}
},
components: {
record,
headerIndex
},
computed: {
...mapState(["user", "familayList", 'MeasureResult', "isConnected", "isBluetoothTyle"]),
userInfo() {
return this.user
},
userList() {
return this.familayList
},
cplist() {
console.log("this.MeasureResult.cplist", this.MeasureResult.cplist)
return this.MeasureResult.cplist
},
info() {
let that = this
that.infoListTop = that.MeasureResult.top_list[0] ? that.MeasureResult.top_list[0] : {}
that.activeHeight = 0
return that.MeasureResult
},
},
onLoad(options) {
let that = this
// #ifdef APP-PLUS
if (options && options.type == 1) {
that.handleUserList()
that.handleBannerList()
}
// #endif
// #ifndef APP-PLUS
that.handleoginversion()
// #endif
uni.onBluetoothAdapterStateChange(function(res) {
that.$store.commit("changeBluetooth", res.available);
})
that.onBLEConnectionStateChange()
},
onPullDownRefresh() {
let that = this
that.isShow = true
that.handleUserList()
that.onBLEConnectionStateChange()
uni.stopPullDownRefresh()
},
watch: {
isConnected: function() {
let that = this
console.log("isConnected", that.isConnected)
if (!that.isConnected) {
that.textLink = "开始连接"
that.islink = -1
}
},
isBluetoothTyle: function() {
let that = this
console.log("isBluetoothTyle", that.isBluetoothTyle)
if (!that.isBluetoothTyle) {
that.textLink = "开始连接"
that.islink = -1
}
},
},
onShow() {
let that = this
console.log("onShow", uni.getStorageSync('isBle'))
uni.onBluetoothAdapterStateChange(function(res) {
that.$store.commit("changeBluetooth", res.available);
})
if (uni.getStorageSync('isBle') && uni.getStorageSync('isBle') == true) {
that.openBluetoothAdapter()
uni.setStorageSync('isBle', false)
console.log("首次添加玩用户后初始化蓝牙", uni.getStorageSync('isBle'))
}
},
methods: {
//
handleoginversion() {
let that = this
that.$model.getloginversion({}).then(res => {
if (res.code == 0) {
that.handleUserList()
that.handleBannerList()
} else {
uni.setStorageSync('token', null)
uni.setStorageSync('aan_id', null)
uni.clearStorageSync()
uni.reLaunch({
url: "/pageTwo/login/login"
})
}
})
},
//
handleUserList() {
let that = this
that.$model.getUserList({
type: 2
}).then(res => {
that.isShow = true
console.log("用户列表", res, uni.getStorageSync('userid'))
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.$store.commit('changeFamilay', res.data)
if (res.data.length) {
let userid = ""
if (uni.getStorageSync('userid')) {
let found = res.data.find(e => e.id == uni.getStorageSync('userid'));
if (found !== undefined) {
userid = found.id
} else {
userid = res.data[0].id
uni.setStorageSync('userid', res.data[0].id)
}
} else {
userid = res.data[0].id
uni.setStorageSync('userid', res.data[0].id)
}
console.log("正确userid", userid)
that.$store.dispatch('getUserInfo', {
aud_id: userid
})
that.$store.dispatch("getResult", {
aud_id: userid
})
that.handleLabelList(userid)
that.handlePublicRecord(userid)
that.openBluetoothAdapter()
}
}).catch(err => {})
},
//
handleLabelList(id) {
let that = this
that.$model.getLabelList({
aud_id: id
}).then(res => {
console.log("公共卡片项目", res)
if (res.code == 0) {
that.$store.commit('changeLabelList', res.data)
}
})
},
//
handlePublicRecord(id) {
let that = this
that.$model.getPublicRecord({
aud_id: id
}).then(res => {
console.log("公共手动记录", res)
if (res.code == 0) {
that.$store.commit('changePublicRecord', res.data)
}
})
},
// banner
handleBannerList() {
let that = this
that.$model.getBannerList({}).then(res => {
if (res.code != 0) {
that.$tools.msg(res.msg)
return
}
that.notices = res.data.notice
that.banner = res.data.banner
that.pop = res.data.pop
that.isCoupon = res.data.pop.length ? true : false
})
},
detail(ite) {
uni.navigateTo({
url: "/pageTwo/webview/webview?id=" + ite.id + '&url=' + ite.jump_url
})
},
//
handleCard() {
uni.navigateTo({
url: "/pageTwo/cardList/card"
})
},
handleTool(ind, path) {
let that = this
if (ind == 8) {
that.handlerRecord(2)
} else {
that.navTo(path)
}
},
//
handlerReport(item) {
console.log("item", item)
let device = item.device_determine ? 1 : 0
uni.navigateTo({
url: item.page_url_report + "?acd_id=" + item.acd_id + '&device=' + device
})
},
//
handlerRecord(id) {
this.rtype = id
this.$store.commit('changeRecord', true)
},
//
handleAddUser() {
uni.navigateTo({
url: "/pageTwo/my/userInfo"
})
},
handleToggleTop(item, index) {
this.infoListTop = item
this.activeHeight = index
},
navTo(url) {
console.log("url", url)
uni.navigateTo({
url: url
})
},
//
openBluetoothAdapter() {
let that = this
that.devicesList = []
uni.openBluetoothAdapter({
success: e => {
that.islink = 0
that.textLink = "蓝牙搜索中"
console.log("蓝牙初始化成功")
that.startBluetoothDeviceDiscovery()
},
fail: err => {
that.islink = -1
that.textLink = that.$tools.getBluetoothAdapter(err)
console.log('初始化蓝牙失败:' + err);
return
}
});
},
//
startBluetoothDeviceDiscovery() {
let that = this
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true, //
interval: 200,
success: res => {
console.log("搜索设备")
that.onBluetoothDeviceFound();
},
fail: res => {}
});
},
/**
* 发现外围设备
*/
onBluetoothDeviceFound() {
var that = this;
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
console.log("name",device.name)
if (!device.name && !device.localName) {
device.advertisData = device.advertisData ? device.advertisData : ''
let value = that.$tools.ab2hex(device.advertisData, "")
let type = value.substring(0, 2)
let id = value.substring(12, 16)
if (type.toLowerCase() == 'c0') {
console.log(value, "id", id)
clearTimeout(myTime);
that.deviceName = "c00002"
device.deviceId = device.deviceId
that.handleDevice(device)
}
return
}
if (device.name.indexOf("G02") != -1) {
clearTimeout(myTime);
that.deviceId = device.deviceId;
that.$Bluetooth.stopBluetoothDevicesDiscovery()
that.handleDevice(device)
return
}
if (device.name.indexOf("Chipsea_BLE") != -1) {
clearTimeout(myTime);
that.deviceId = device.deviceId;
that.$Bluetooth.stopBluetoothDevicesDiscovery()
that.handleDevice(device)
return
}
if (device.name.indexOf('YPC') != -1) {
clearTimeout(myTime);
device.deviceId = device.deviceId
that.$Bluetooth.stopBluetoothDevicesDiscovery()
that.handleDevice(device)
return
}
if (device.name.toLowerCase().indexOf('da') != -1) {
clearTimeout(myTime);
device.deviceId = device.deviceId
that.handleDevice(device)
return
}
if (device.name.toLowerCase().indexOf('pcl') != -1 || (device.localName && device
.localName.toLowerCase().indexOf('pcl') != -1)) {
clearTimeout(myTime);
that.deviceName = device.name
that.deviceId = device.deviceId;
that.handleDevice(device)
return
}
})
});
that.handleMyTime()
},
handleDevice(device) {
let that = this
const foundDevices = that.devicesList
const idx = that.$tools.inArray(foundDevices, "deviceId", device.deviceId)
console.log("1111111", device.name)
if (idx === -1) {
//
if (device.name.toLowerCase().indexOf("pcl") != -1) {
that.devicesList.push(device)
uni.navigateTo({
url: "/pageTwo/devices/PCL?deviceId=" + device.deviceId
})
return
}
//
if (that.deviceName == "c00002") {
that.devicesList.push(device)
uni.navigateTo({
url: "/pageTwo/devices/PCL22?deviceId=" + device.deviceId
})
return
}
//
if (device.name.toLowerCase() == "da") {
that.devicesList.push(device)
uni.navigateTo({
url: "/pageTwo/devices/PCL22S?deviceId=" + device.deviceId
})
return
}
//
if (device.name.indexOf("G02") != -1) {
that.devicesList.push(device)
uni.navigateTo({
url: "/pageTwo/devices/G02?deviceId=" + device.deviceId
})
return
}
//
if (device.name.indexOf("YPC") != -1) {
that.devicesList.push(device)
uni.navigateTo({
url: "/pages/skiping/skip?deviceId=" + device.deviceId
})
return
}
//
if (device.name.indexOf("Chipsea_BLE") != -1) {
that.devicesList.push(device)
uni.navigateTo({
url: "/pageTwo/devices/B20?deviceId=" + device.deviceId
})
return
}
}
},
handleMyTime() {
var that = this;
myTime = setTimeout(function() {
if (!that.devicesList.length) {
that.islink = -1
that.textLink = "未搜索到有效设备,重新搜索"
clearTimeout(myTime);
that.$Bluetooth.stopBluetoothDevicesDiscovery()
}
}, 50000);
},
// 广
getBlereload() {
let that = this
that.islink = -1
that.textLink = "重新测量"
},
//
onBLEConnectionStateChange() {
let that = this
uni.onBLEConnectionStateChange(function(res) {
console.log("监听蓝牙连接状态", res.connected)
that.$store.commit("changeConnected", res.connected);
})
},
/**
* 断开蓝牙模块
*/
closeBluetoothAdapter() {
let that = this;
uni.closeBluetoothAdapter({
success: res => {
console.log('蓝牙模块关闭成功');
}
})
},
/**
* 断开蓝牙连接
*/
closeBLEConnection() {
var that = this;
uni.closeBLEConnection({
deviceId: that.deviceId,
success: res => {
console.log('断开蓝牙连接成功');
that.$store.commit("changeConnected", false);
}
});
},
}
}
</script>
<style lang="scss" scoped>
@import "@/scss/body.scss";
/deep/.header {
width: 100%;
.top {
color: #fff;
background: $maincolor ;
}
}
/deep/.cityList {
margin-top: -36px;
}
.list {
margin-top: 0rpx;
padding: 0;
}
.blueBtn {
color: #fff;
padding: 5px !important;
background-color: #2397f1;
}
.orangeBtn {
color: #fff;
padding: 5px !important;
background-color: #FF974C;
}
.border {
border-bottom: 1px solid #f7f7f7;
}
.target {
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
z-index: 99;
.bold {
width: 45%;
text-align: left;
}
.btnGroup {
width: 50%;
display: flex;
justify-content: space-between;
}
}
.item {
position: relative;
z-index: 99;
}
.size32 {
font-size: 80rpx;
}
.card {
position: relative;
overflow: hidden;
}
.boxBg {
width: 250rpx;
height: 215rpx;
position: absolute;
right: 15px;
z-index: 9;
bottom: -50rpx;
image {
width: 100%;
height: 100%;
}
}
.content {
min-height: 100vh;
padding-bottom: 15px;
background-color: #f7f7f7;
}
.bleTips {
height: 35px;
line-height: 35px;
margin: 15px 10px 10px;
background: #fff;
border-radius: 10px;
text-align: center;
box-shadow: 0px 1px 5px 2px #dfe2e1fc;
}
.bleTips2 {
background: #fea606;
color: #fff;
}
//
.tools_l {
width: 100%;
display: flex;
flex-wrap: wrap;
padding-top: 15px;
background: #fff;
justify-content: space-between;
.list {
width: 20%;
text-align: center;
font-size: 14px;
margin-bottom: 20px;
.text {
margin-top: 5px;
color: #666;
font-size: 14px;
}
}
image {
width: 35px;
height: 35px;
}
}
.activeHeight {
padding-bottom: 10px;
border-bottom: 2px solid $maincolor;
}
</style>

View File

@ -1,52 +0,0 @@
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>

102
pages/lunging/charts.vue Normal file
View File

@ -0,0 +1,102 @@
<template>
<view class="TrendPage">
<view class="listC">
<view @click="handleActive(1)" :class="[active==1?'active':'']">当天</view>
<view @click="handleActive(2)" :class="[active==2?'active':'']">月度</view>
<view @click="handleActive(3)" :class="[active==3?'active':'']">年度</view>
</view>
<view class="box">
<!-- 时间选择 -->
<view class="boxTime">
<picker mode="date" class="f-l" :value="startDate" @change="handStartTimeH"
:fields="active==1?'day':active==2?'month':'year'">
<view class="uni-input">{{time}}<uni-icons type="bottom"></uni-icons></view>
</picker>
</view>
<!-- 曲线图 -->
<view class="boxLine">
<view class="line" v-for="(item,index) in weightList">
<view v-if="item.line.categories.length">
<qiunDataCharts type="column" :chartData="item.line" :canvas2d="true" :canvasId="'lung'+index"
:Width="340" :Height="250" :animation="false"
:opts="{enableScroll:true,xAxis:{scrollShow:false,itemCount:3}}" :ontouch="true" />
</view>
<view class="nolist" v-else>
<image src="../../static/none.png"></image>
<text>暂无数据请手动添加~</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from "vuex";
import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
export default {
components: {
qiunDataCharts,
},
computed: {
...mapState(["user"]),
userInfo: function() {
return this.user
},
startDate() {
return this.$tools.getDate("start")
},
},
onLoad() {
let that = this
this.active = 1
this.time = this.startDate
that.getList()
},
methods: {
getList() {
let that = this
that.$model.getLungTrendList({
aud_id: uni.getStorageSync('userid'),
time: that.time,
}).then(res => {
console.log("肺活量曲线", res.data)
that.weightList = res.data
})
},
handleActive(ite) {
let that = this
that.handTrue = false
that.time = ite == 1 ? this.startDate : ite == 2 ? this.$tools.getDate("month") : this.$tools.getDate(
"year")
that.getList()
that.$nextTick(function() {
that.handTrue = true
})
that.active = ite
},
handStartTimeH(e) {
let that = this
that.time = e.target.value
that.getList()
},
navTo(url) {
uni.navigateTo({
url: url
})
}
},
data() {
return {
weightList: [],
handTrue: true,
active: 1,
time: "",
};
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,130 @@
<template>
<view class="content">
<!-- -->
<view class="skiptop">
<!-- <view class="status" @click="$Bluetooth.handleDevicesMac(isdevice,acd_id)"><text>设备连接</text></view> -->
<view class="item">
<view class="item-ite">平均吸气肺活量<text>{{info?info.average:'--'}}</text></view>
<view class="item-ite">吸气速度<text>--</text></view>
<view class="item-ite">是否达标<text>{{info?info.level:'--'}}</text></view>
</view>
</view>
<!--自由训练 -->
<view class="box1">
<view class="time">{{info?info.time:''}}</view>
<!-- <view class="LiuS">吸气速度 <text class="cgreen ml-5">{{info?info.flow_val:'--'}}L/min</text></view> -->
<view class="item">
<view class="image">
<image src="../../static/bae.png" mode="widthFix"></image>
</view>
<view class="center mt-15">
<view class="level"></view>
<view class="level level-bg" :style="{'top':info?Number(100 - info.offset)+'%':'100%'}"></view>
<view class="level-item" v-if="info">
<view class="ite" v-for="(ite,ind) in info.list" :style="{'height':100/info.list.length+'%'}">
{{ite.text}}</view>
</view>
</view>
</view>
<view class="val" v-if="info">
<text>{{info.average}}</text>
吸气肺活量平均值
</view>
</view>
<!-- -->
<view class="gridList">
<view class="data">
<view class="item" @click="navTo('/pages/lunging/charts')">
<view class="image">
<image src="../../static/charts.png"></image>
</view>
<view class="name">运动曲线</view>
</view>
<view class="item" @click="navTo('/pageTwo/history/history?acd_id='+acd_id)">
<view class="image">
<image src="../../static/add.png"></image>
</view>
<view class="name">历史记录</view>
</view>
<view class="item" @click="navTo('/pageTwo/compk/contrast?acd_id='+acd_id)">
<view class="image">
<image src="../../static/pk.png"></image>
</view>
<view class="name">数据对比</view>
</view>
<view class="item" @click="$store.commit('changeRecord',true)">
<view class="image">
<image src="../../static/history.png"></image>
</view>
<view class="name">添加记录</view>
</view>
</view>
</view>
<!-- 手动记录 -->
<record :rtype="acd_id"></record>
</view>
</template>
<script>
import {
mapState
} from "vuex";
import record from '@/element/manuallyAdd/record.vue';
export default {
data() {
return {
LiuS: 0,
acd_id: 8,
isdevice: true,
}
},
components: {
record
},
computed: {
...mapState(["MeasureLung"]),
info() {
return this.MeasureLung
}
},
onLoad(options) {
let that = this
that.acd_id = options.acd_id
that.isdevice = options.device
that.$store.dispatch("getLungResult", {
aud_id: uni.getStorageSync('userid')
})
},
onPullDownRefresh() {
let that = this
that.$store.dispatch("getLungResult", {
aud_id: uni.getStorageSync('userid')
})
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000);
},
methods: {
//
reload() {
let that = this
console.log('重新加载');
this.$nextTick(() => {
that.$store.dispatch("getLungResult", {
aud_id: uni.getStorageSync('userid')
})
})
},
navTo(url) {
uni.navigateTo({
url: url
})
},
}
}
</script>
<style lang="scss" scoped>
@import "@/scss/lunging.scss";
</style>

Some files were not shown because too many files have changed in this diff Show More