fix: 新增详情
This commit is contained in:
parent
c8b504ce03
commit
09ee8475e3
81
App.vue
81
App.vue
|
|
@ -7,9 +7,7 @@
|
|||
plus.navigator.closeSplashscreen();
|
||||
// #endif
|
||||
},
|
||||
onLaunch: function() {
|
||||
|
||||
console.log('App Launch')
|
||||
onLaunch: async function() {
|
||||
uni.getSystemInfo({
|
||||
success: function(e) {
|
||||
// #ifndef MP
|
||||
|
|
@ -33,13 +31,88 @@
|
|||
Vue.prototype.CustomBar = e.statusBarHeight + e.titleBarHeight;
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// 是否更新APP
|
||||
// #ifdef APP-PLUS
|
||||
await this.getIsUpdata();
|
||||
// #endif
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App 开启')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App 关闭')
|
||||
},
|
||||
methods: {
|
||||
getIsUpdata() {
|
||||
// 获取本地应用资源版本号
|
||||
plus.runtime.getProperty(plus.runtime.appid, (info) => {
|
||||
this.version = info.version; // 版本号 1.0.0
|
||||
this.versionCode = info.versionCode ; // 版本号名称 100
|
||||
let params = {
|
||||
version: info.version
|
||||
};
|
||||
this.$store.dispatch('api/getVersion', params).then(res => {
|
||||
if (this.compareVersions(res.data.version, params.version) == 1) {
|
||||
uni.showModal({
|
||||
title: "版本更新",
|
||||
content: '有新的版本发布,是否立即进行新版本下载?',
|
||||
confirmText:'立即更新',
|
||||
cancelText:'稍后进行',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
//#ifdef APP-PLUS
|
||||
// encodeURI要大写
|
||||
plus.runtime.openURL(encodeURI(`http://ydy.baimajingxuan.com`));
|
||||
//#endif
|
||||
} else if (res.cancel) {
|
||||
console.log('稍后更新');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 下面执行需要更新的安卓端热更新代码
|
||||
// var data = {
|
||||
// // 版本更新内容 支持<br>自动换行
|
||||
// describe: "1.修复已知问题2.优化用户体验3.新增聊天室4.修复部分bug4.修复部分bug14.",
|
||||
// edition_url: 'https://img.agrimedia.cn/bmsc/apps/1.1.8s.wgt', //apk、wgt包下载地址或者应用市场地址 安卓应用市场 market://details?id=xxxx 苹果store itms-apps://itunes.apple.com/cn/app/xxxxxx
|
||||
// edition_force: 0, //是否强制更新 0代表否 1代表是, 弹窗关闭
|
||||
// package_type: 1, //0是整包升级(apk或者appstore或者安卓应用市场) 1是wgt升级
|
||||
// edition_number: 100, //版本号 最重要的manifest里的版本号 (检查更新主要以服务器返回的edition_number版本号是否大于当前app的版本号来实现是否更新)
|
||||
// edition_name: '1.0.0', // 版本名称 manifest里的版本名称
|
||||
// }
|
||||
|
||||
// // 这里也可以让前端判断本地和接口返回的版本号是否一致
|
||||
// if (Number(this.versionCode) == 117) {
|
||||
// //跳转更新页面 (注意!!!如果pages.json第一页的代码里有一打开就跳转其他页面的操作,下面这行代码最好写在setTimeout里面设置延时3到5秒再执行)
|
||||
// uni.navigateTo({
|
||||
// url: `/uni_modules/rt-uni-update/components/rt-uni-update/rt-uni-update?obj=${JSON.stringify(data)}`
|
||||
// });
|
||||
// }
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
compareVersions(v1, v2) {
|
||||
const v1Parts = v1.split('.').map(Number);
|
||||
const v2Parts = v2.split('.').map(Number);
|
||||
|
||||
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
||||
const v1Part = v1Parts[i] || 0;
|
||||
const v2Part = v2Parts[i] || 0;
|
||||
|
||||
if (v1Part > v2Part) {
|
||||
return 1;
|
||||
}
|
||||
if (v1Part < v2Part) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,15 @@ export const getDayInfo = (data) => {
|
|||
return post('watch/device/getDayInfo', data)
|
||||
}
|
||||
|
||||
export const getDeviceListDays = (data) => {
|
||||
return post('watch/device/getDeviceListDays', data)
|
||||
}
|
||||
|
||||
// 获取版本号
|
||||
export const getVersion = (data) => {
|
||||
return post('watch/version/index', data)
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
code,
|
||||
|
|
@ -37,5 +46,7 @@ export default {
|
|||
sendSms,
|
||||
register,
|
||||
getBindUserDeviceId,
|
||||
getDayInfo
|
||||
getDayInfo,
|
||||
getDeviceListDays,
|
||||
getVersion
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name" : "family-app",
|
||||
"name" : "中鼎云医",
|
||||
"appid" : "__UNI__24DA8DD",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
|
|
@ -70,34 +70,34 @@
|
|||
},
|
||||
"vueVersion" : "2",
|
||||
"h5" : {
|
||||
"async" : {
|
||||
"delay" : "10000" // 这个时间内页面js已经加载了,所以不展示默认的loading
|
||||
},
|
||||
"router" : {
|
||||
"base" : "./"
|
||||
},
|
||||
"devServer" : {
|
||||
"disableHostCheck" : true, // 开启可以用自己的域名
|
||||
"proxy": {
|
||||
"/watch": {
|
||||
"target": "http://test.sc2.agrimedia.cn",
|
||||
"changeOrigin": true,
|
||||
"secure": false
|
||||
// "pathRewrite": { //重写url
|
||||
// "^/watch": ""
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
"title" : "智能终端",
|
||||
"optimization" : {
|
||||
"treeShaking" : {
|
||||
"enable" : false
|
||||
}
|
||||
},
|
||||
"template" : "template.h5.html",
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
}
|
||||
"async" : {
|
||||
"delay" : "10000" // 这个时间内页面js已经加载了,所以不展示默认的loading
|
||||
},
|
||||
"router" : {
|
||||
"base" : "./"
|
||||
},
|
||||
"devServer" : {
|
||||
"disableHostCheck" : true, // 开启可以用自己的域名
|
||||
"proxy" : {
|
||||
"/watch" : {
|
||||
"target" : "http://test.sc2.agrimedia.cn",
|
||||
"changeOrigin" : true,
|
||||
"secure" : false
|
||||
}
|
||||
}
|
||||
},
|
||||
// "pathRewrite": { //重写url
|
||||
// "^/watch": ""
|
||||
// }
|
||||
"title" : "智能终端",
|
||||
"optimization" : {
|
||||
"treeShaking" : {
|
||||
"enable" : false
|
||||
}
|
||||
},
|
||||
"template" : "template.h5.html",
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
{
|
||||
"path": "pages/login/login",
|
||||
"style": {}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/detail",
|
||||
"style": {}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/forget",
|
||||
|
|
|
|||
|
|
@ -4,11 +4,8 @@
|
|||
<view class="content">
|
||||
<view class="content-header">
|
||||
<view class="title">设备</view>
|
||||
<!-- <view class="add" @click="toAdd()">
|
||||
<image src="/static/image/add-icon.png" mode=""></image>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="content-item" v-for="(item, index) in deviceList">
|
||||
<view class="content-item" v-for="(item, index) in deviceList" v-if="item.user">
|
||||
<view class="title">
|
||||
<text>绑定人: {{item.user.mobile}}</text>
|
||||
</view>
|
||||
|
|
@ -36,16 +33,14 @@
|
|||
console.log(this.deviceList)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// toAdd() {
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/device/adddevice'
|
||||
// })
|
||||
// },
|
||||
methods: {
|
||||
clickLeft() {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
getNameByKey(key) {
|
||||
return this.keyNameMap[key] || "Key not found";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
<template>
|
||||
<z-paging ref="paging" v-model="dataList" @query="queryList">
|
||||
<tm-nav-bar left-icon="arrow-left" :title="desc? getNameByKey(desc) : getNameByKey(type)" @clickLeft="back" />
|
||||
<view class="content">
|
||||
<view class="over" style="margin-top: 30rpx" @click="flag = !flag">
|
||||
<text>日期筛选</text>
|
||||
<uni-icons type="down" size="24"></uni-icons>
|
||||
</view>
|
||||
<view class="time" v-show="flag">
|
||||
<punch-calendar @switchMonth="switchMonth" @chooseDay="chooseDay" :errorList="errorList" :successList="successList" ref="calendar"></punch-calendar>
|
||||
</view>
|
||||
<view class="list" v-if="dataList.length">
|
||||
<view class="row" v-for="(item, index) in dataList" :key="index">
|
||||
<view class="data">
|
||||
<image src="https://img.agrimedia.cn/apptest/%E6%89%8B%E8%A1%A8-%E7%BA%BF%E6%80%A73-0.png" mode="widthFix"></image>
|
||||
<view v-if="type == 'step'">
|
||||
疲劳:{{item.data_msg.wear}}
|
||||
运动量:{{item.data_msg.amountOfExercise}}
|
||||
</view>
|
||||
<view v-if="type == 'bloodPressure'">
|
||||
{{item.data_msg.bloodPressureHigh}}/{{item.data_msg.bloodPressureLow}}
|
||||
</view>
|
||||
<view v-if="type == 'bloodGlucose'">
|
||||
{{item.data_msg}}
|
||||
</view>
|
||||
<view v-if="type == 'bloodLiquid' && desc == 'uricAcidVal'">
|
||||
{{item.data_msg.uricAcidVal}}
|
||||
</view>
|
||||
<view v-if="type == 'bloodLiquid' && desc !== 'uricAcidVal'" style="font-size: 24rpx;">
|
||||
<view>胆固醇:{{item.data_msg.cholesterol/100}} 三酰甘油:{{item.data_msg.triacylglycerol/100}}</view>
|
||||
<view>高密度脂蛋白:{{item.data_msg.highDensity/100}}低密度脂蛋白:{{item.data_msg.lowDensity}}</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
{{getArrMaxValue(item.data_msg)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="time">
|
||||
{{item.date_str}} {{item.hour_minute}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getArrMaxValue } from '@/utils/utils.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
type: '',
|
||||
desc: '',
|
||||
dataList: [],
|
||||
keyNameMap: {
|
||||
bloodGlucose: "血糖",
|
||||
bloodOxygen: "血氧",
|
||||
bloodPressure: '血压',
|
||||
heartReat: '心率',
|
||||
bloodLiquid: "血液",
|
||||
uricAcidVal: '尿酸',
|
||||
meiTuo: '梅拖',
|
||||
pulseReat: '脉率',
|
||||
updataDate: '更新时间',
|
||||
step: '步数'
|
||||
},
|
||||
time: '',
|
||||
flag: false,
|
||||
successList: ['1676995200000'],
|
||||
errorList: ['1676908800000'],
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// 初始化
|
||||
this.$refs.calendar.initCalendar()
|
||||
|
||||
// 模拟异步赋值
|
||||
let timer = setTimeout(()=>{
|
||||
this.addTimer()
|
||||
},2000)
|
||||
},
|
||||
|
||||
// onLoad() {
|
||||
// // 初始化
|
||||
// this.$refs.calendar.initCalendar()
|
||||
|
||||
// // 模拟异步赋值
|
||||
// let timer = setTimeout(()=>{
|
||||
// this.addTimer()
|
||||
// },2000)
|
||||
// },
|
||||
|
||||
onShow(e) {
|
||||
let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
|
||||
let curRoute = routes[routes.length - 1].route //获取当前页面路由
|
||||
let curParam = routes[routes.length - 1].options; //获取路由参数
|
||||
// 拼接参数
|
||||
let param = ''
|
||||
for (let key in curParam) {
|
||||
param += '&' + key + '=' + curParam[key]
|
||||
}
|
||||
this.type = curParam.type;
|
||||
this.desc = curParam.desc;
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
getArrMaxValue,
|
||||
queryList(pageNo, pageSize) {
|
||||
this.$store.dispatch('api/getDeviceListDays', {
|
||||
type: this.type,
|
||||
device_real_time: this.time
|
||||
}).then(res => {
|
||||
this.$refs.paging.completeByTotal(res.data, res.total);
|
||||
});
|
||||
},
|
||||
|
||||
getNameByKey(key) {
|
||||
return this.keyNameMap[key] || "Key not found";
|
||||
},
|
||||
|
||||
addTimer() {
|
||||
this.successList = [...this.successList, '1681920000000']
|
||||
},
|
||||
|
||||
// 点击某一天
|
||||
chooseDay(val) {
|
||||
this.time = val.year + '-' + val.month + '-' + val.day;
|
||||
this.$refs.paging.reload();
|
||||
},
|
||||
|
||||
back() {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
.over {
|
||||
margin: 0rpx 30rpx;
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 20rpx;
|
||||
font-weight: 800;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.list {
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
padding: 30rpx;
|
||||
margin: 30rpx 30rpx;
|
||||
border-radius: 30rpx;
|
||||
.row {
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
font-size: 36rpx;
|
||||
image {
|
||||
width: 50rpx;
|
||||
}
|
||||
}
|
||||
.time {
|
||||
font-weight: 300;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -15,34 +15,37 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item row">
|
||||
<view class="content-item row" @click="toPage('/pages/index/detail?type=step')">
|
||||
<view class="item">
|
||||
<view class="title">卡路里</view>
|
||||
<view class="row-date">
|
||||
{{dataLists.step.calorie}}
|
||||
{{dataLists.step? dataLists.step.calorie/10 : '--'}}
|
||||
<text>千卡</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">步数</view>
|
||||
<view class="row-date">
|
||||
{{dataLists.step.step}}
|
||||
{{dataLists.step? dataLists.step.step : '--'}}
|
||||
<text>步</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">距离</view>
|
||||
<view class="row-date">
|
||||
{{dataLists.step.distance}}
|
||||
{{dataLists.step? dataLists.step.distance/100 : '--'}}
|
||||
<text>公里</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="row-time">
|
||||
{{dataLists.updataDate}}
|
||||
{{formatDateTime(dataLists.updataDate)}}
|
||||
</view>
|
||||
<view class="bg">
|
||||
<image src="../../static/icon/血糖.png" mode="widthFix"></image>
|
||||
<!-- <image src="../../static/icon/血糖.png" mode="widthFix"></image> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="content-item" @click="toPage('/pages/index/detail?type=bloodGlucose')">
|
||||
<view class="title">
|
||||
{{getNameByKey('bloodGlucose')}}
|
||||
</view>
|
||||
|
|
@ -57,7 +60,7 @@
|
|||
<image src="../../static/icon/血糖.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="content-item" @click="toPage('/pages/index/detail?type=bloodOxygen')">
|
||||
<view class="title">
|
||||
{{getNameByKey('bloodOxygen')}}
|
||||
</view>
|
||||
|
|
@ -72,7 +75,7 @@
|
|||
<image src="../../static/icon/血氧.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="content-item" @click="toPage('/pages/index/detail?type=bloodPressure')">
|
||||
<view class="title">
|
||||
{{getNameByKey('bloodPressure')}}
|
||||
</view>
|
||||
|
|
@ -87,7 +90,7 @@
|
|||
<image src="../../static/icon/血压.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="content-item" @click="toPage('/pages/index/detail?type=heartReat')">
|
||||
<view class="title">
|
||||
{{getNameByKey('heartReat')}}
|
||||
</view>
|
||||
|
|
@ -102,7 +105,7 @@
|
|||
<image src="../../static/icon/脉率.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="content-item" @click="toPage('/pages/index/detail?type=meiTuo')">
|
||||
<view class="title">
|
||||
{{getNameByKey('meiTuo')}}
|
||||
</view>
|
||||
|
|
@ -117,7 +120,7 @@
|
|||
<image src="../../static/icon/心率.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="content-item" @click="toPage('/pages/index/detail?type=bloodLiquid&desc=uricAcidVal')">
|
||||
<view class="title">
|
||||
尿酸
|
||||
</view>
|
||||
|
|
@ -133,7 +136,7 @@
|
|||
</view>
|
||||
</view>
|
||||
|
||||
<view class="content-item" style="height: 360rpx">
|
||||
<view class="content-item" style="height: 430rpx" @click="toPage('/pages/index/detail?type=bloodLiquid')">
|
||||
<view class="title">
|
||||
{{getNameByKey('bloodLiquid')}}
|
||||
</view>
|
||||
|
|
@ -215,10 +218,20 @@
|
|||
this.dataLists = res.data_msg;
|
||||
this.$refs.paging.complete();
|
||||
});
|
||||
},
|
||||
toPage(url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
getNameByKey(key) {
|
||||
return this.keyNameMap[key] || "Key not found";
|
||||
}
|
||||
},
|
||||
formatDateTime(dateTimeStr) {
|
||||
if (dateTimeStr) {
|
||||
return dateTimeStr.replace(/-/g, ' ').replace(' ', ' ', 2).replace(' ', ':');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -291,6 +304,7 @@
|
|||
.title {
|
||||
font-size: 38rpx;
|
||||
font-weight: 800;
|
||||
margin-bottom: 14rpx;
|
||||
}
|
||||
.row-time {
|
||||
position: absolute;
|
||||
|
|
@ -320,6 +334,12 @@
|
|||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
text {
|
||||
opacity: .5;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
padding-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.date {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -4,10 +4,10 @@
|
|||
<view class="head"></view>
|
||||
<!-- 个人信息模块 -->
|
||||
<view class="user-info-box">
|
||||
<view class="avatar-box" @click="logout()">
|
||||
<view class="avatar-box">
|
||||
<image class="avatar" src="../../static/a-ziyuan85.png"></image>
|
||||
<view class="avatar-text">
|
||||
<view class="name">登录</view>
|
||||
<view class="name">{{getApiToken? '用户':'去登录'}}</view>
|
||||
<view class="desc"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -97,7 +97,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import store from "@/store/index.js";
|
||||
import store from "@/store/index.js";
|
||||
import { mapGetters } from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -106,6 +107,11 @@
|
|||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
getApiToken: "api/getApiToken"
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import {
|
|||
register,
|
||||
getBindUserDeviceId,
|
||||
getDayInfo,
|
||||
getDeviceListDays,
|
||||
getVersion
|
||||
} from '@/common/api.js';
|
||||
|
||||
let state = {
|
||||
|
|
@ -58,6 +60,14 @@ let state = {
|
|||
async getDayInfo({commit}, data) {
|
||||
const res = await getDayInfo(data)
|
||||
return res
|
||||
},
|
||||
async getDeviceListDays({commit}, data) {
|
||||
const res = await getDeviceListDays(data)
|
||||
return res
|
||||
},
|
||||
async getVersion({commit}, data) {
|
||||
const res = await getVersion(data)
|
||||
return res
|
||||
}
|
||||
}
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
## 1.0.6(2023-04-20)
|
||||
更新ios端 date问题
|
||||
## 1.0.5(2023-04-20)
|
||||
添加切换方法,更新使用demo
|
||||
## 1.0.4(2023-03-30)
|
||||
修改初始化以及分阶段赋值
|
||||
## 1.0.3(2023-03-12)
|
||||
完善文档
|
||||
## 1.0.2(2023-03-11)
|
||||
修复异步赋值不展示问题
|
||||
## 1.0.1(2023-02-27)
|
||||
修改文档,添加github地址
|
||||
## 1.0.0(2023-02-24)
|
||||
第一版本,后续会持续优化
|
||||
|
|
@ -0,0 +1,464 @@
|
|||
<template>
|
||||
<view class="punch-calendar-wrapper">
|
||||
<view class="calendar">
|
||||
<view class="top flex-bt padding-32">
|
||||
<view class="prev flex-center" @click="switchMonth('prev')">
|
||||
<image class="icon" src="../../static/images/calendar-prev.png"></image>
|
||||
</view>
|
||||
<text>{{calendarConfig.yearAndMonth}}</text>
|
||||
<view class="next flex-center" @click="switchMonth('next')">
|
||||
<image class="icon" :src="nextIconStyle"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="center">
|
||||
<view class="week flex-bt">
|
||||
<view class="items" v-for="item in calendarConfig.week" :key="item">{{item}}</view>
|
||||
</view>
|
||||
<view class="day">
|
||||
<template v-for="(item,index) in calendarConfig.day">
|
||||
<view class="flex-start" :key="index" v-if="item.open">
|
||||
<view class="items flex-center" :class="[child.tag]" v-for="(child,childIndex) in item.list"
|
||||
:key="childIndex">
|
||||
<text :class="[child.className,child.active]" @click="chooseDay(item,child)">
|
||||
{{child.value}}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom flex-center" @click="fold">
|
||||
<image src="../../static/images/cakebdar-open.png" :class="[!calendarConfig.fold ? 'active' : '']"
|
||||
class="icon"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'punch-calendar',
|
||||
props: {
|
||||
// 成功打卡
|
||||
successList: {
|
||||
type: Array,
|
||||
default: ()=> []
|
||||
},
|
||||
|
||||
// 打卡异常点
|
||||
errorList: {
|
||||
type: Array,
|
||||
default: ()=>[]
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
successArr: [],
|
||||
errorArr: [],
|
||||
calendarConfig: {
|
||||
week: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
nowYear: '', //当前日历 年
|
||||
nowMonth: '', //当前日历 月
|
||||
nowDay: '', //当前日历 日
|
||||
day: [], //日历列表
|
||||
fold: false, // 展开/折叠状态
|
||||
yearAndMonth: '', // 当前日历年月
|
||||
needClock: true, //当天是否需要打卡
|
||||
},
|
||||
monthStatisticList: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nextIconStyle: function() {
|
||||
const {
|
||||
year,
|
||||
month
|
||||
} = this.getNowDate()
|
||||
const {
|
||||
nowYear,
|
||||
nowMonth
|
||||
} = this.calendarConfig
|
||||
if (nowYear == year && nowMonth == month) {
|
||||
return '../../static/images/calendar-next.png';
|
||||
} else {
|
||||
return '../../static/images/calendar-next-active.png';
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
successList: {
|
||||
handler(val) {
|
||||
this.successArr = JSON.parse(JSON.stringify(val))
|
||||
this.initCalendar(false)
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
errorList: {
|
||||
handler(val) {
|
||||
this.errorArr = JSON.parse(JSON.stringify(val))
|
||||
this.initCalendar(false)
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
//切换日历
|
||||
switchMonth(type = 'next') {
|
||||
let {nowYear, nowMonth} = this.calendarConfig
|
||||
let {year, month, day} = this.getNowDate()
|
||||
if(type == 'next' && nowYear == year && nowMonth == month)return false;
|
||||
if(type == 'prev'){
|
||||
if (nowMonth <= 1) {
|
||||
nowMonth = 12
|
||||
nowYear -= 1
|
||||
} else {
|
||||
nowMonth--;
|
||||
}
|
||||
}else{
|
||||
if (nowMonth >= 12) {
|
||||
nowMonth = 1
|
||||
nowYear += 1
|
||||
} else {
|
||||
nowMonth++;
|
||||
}
|
||||
}
|
||||
this.$emit('switchMonth', type, nowYear, nowMonth)
|
||||
this.calendarConfig.nowYear = nowYear
|
||||
this.calendarConfig.nowMonth = nowMonth
|
||||
this.calendarConfig.nowDay = (nowYear == year && nowMonth == month) ? day : ''
|
||||
this.calendarConfig.day = this.calendar(nowYear, nowMonth, this.calendarConfig.nowDay, this.calendarConfig.fold, this.successArr, this.errorArr)
|
||||
this.calendarConfig.yearAndMonth = this.monDetail(nowYear, nowMonth)
|
||||
|
||||
|
||||
},
|
||||
|
||||
chooseDay(item, child) {
|
||||
if(child.className == 'last' || child.className == 'nextMonth')return false;
|
||||
this.$emit('chooseDay',child)
|
||||
this.calendarConfig.day.map(parent=>{
|
||||
parent.list.map(child=>{
|
||||
child.className == 'active' && (child.className = '')
|
||||
return child
|
||||
})
|
||||
return parent
|
||||
})
|
||||
child.className = 'active'
|
||||
},
|
||||
|
||||
// 展开/折叠
|
||||
fold(){
|
||||
const {now, year, month, day} = this.getNowDate()
|
||||
const {nowYear, nowMonth} = this.calendarConfig
|
||||
this.calendarConfig.day.map((parent,index)=>{
|
||||
if(!this.calendarConfig.fold){
|
||||
parent.open = true
|
||||
}else{
|
||||
if(nowYear == year && nowMonth == month){
|
||||
parent.open = parent.list.reduce((result, child)=>{
|
||||
if(child.value == day && child.className !== 'last' && child.className !== 'nextMonth'){
|
||||
result = true
|
||||
}
|
||||
return result
|
||||
}, false)
|
||||
}else{
|
||||
parent.open = index == 0 ? true : false
|
||||
}
|
||||
}
|
||||
return parent
|
||||
})
|
||||
this.calendarConfig.fold = !this.calendarConfig.fold
|
||||
},
|
||||
|
||||
// 初始化
|
||||
initCalendar(nowDate = true) {
|
||||
if(nowDate) {
|
||||
const { year, month, day } = this.getNowDate()
|
||||
this.calendarConfig.nowYear = year
|
||||
this.calendarConfig.nowMonth = month
|
||||
this.calendarConfig.nowDay = day
|
||||
}
|
||||
const {nowYear, nowMonth, nowDay} = this.calendarConfig
|
||||
|
||||
// 渲染日历
|
||||
this.calendarConfig.day = this.calendar(nowYear, nowMonth, nowDay, this.calendarConfig.fold, this.successArr, this.errorArr)
|
||||
// 日历title
|
||||
this.calendarConfig.yearAndMonth = this.monDetail(nowYear, nowMonth)
|
||||
},
|
||||
|
||||
// 获取当前年月日
|
||||
getNowDate(){
|
||||
let now = new Date()
|
||||
let year = now.getFullYear()
|
||||
let month = now.getMonth() + 1
|
||||
let day = now.getDate()
|
||||
return {now, year, month, day}
|
||||
},
|
||||
|
||||
// 显示当前年月
|
||||
monDetail(ynow, mnow) {
|
||||
return `${ynow}年${mnow}月`
|
||||
},
|
||||
|
||||
//判断是否为闰年
|
||||
is_leap(year) {
|
||||
let res = year % 100 == 0 ? (year % 400 == 0 ? 1 : 0) : (year % 4 == 0 ? 1 : 0)
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 渲染日历
|
||||
* ynow 年
|
||||
* mnow 月
|
||||
* dnow 日
|
||||
* fold 折叠状态
|
||||
* successArr 需要打卡
|
||||
* errorArr 异常标记
|
||||
**/
|
||||
calendar(ynow, mnow, dnow, fold, successArr = [], errorArr = []) {
|
||||
let arr = []
|
||||
var nlstr = new Date(ynow, mnow - 1, 1)
|
||||
var firstday = nlstr.getDay()
|
||||
const {now, year, month, day} = this.getNowDate()
|
||||
//每个月的天数
|
||||
var m_days = new Array(31, 28 + this.is_leap(ynow), 31, 30, 31, 31, 30, 31, 30, 31, 30, 31)
|
||||
//当前月天数+第一天是星期几的数值 获得 表格行数
|
||||
var tr_str = Math.ceil((m_days[mnow-1] + firstday) / 7)
|
||||
var i, k, idx, date_str;
|
||||
for (i = 0; i < tr_str; i++) {
|
||||
//表格每行的单元格
|
||||
let row = []
|
||||
for (k = 0; k < 7; k++) {
|
||||
//单元格自然序列号
|
||||
idx = i * 7 + k;
|
||||
//计算日期
|
||||
date_str = idx - firstday + 1;
|
||||
|
||||
if(date_str <= 0){
|
||||
// 处理上月空缺
|
||||
row.push({ value: '', className: '' })
|
||||
|
||||
}else if(year == ynow && month == mnow){
|
||||
if(date_str > m_days[mnow-1]) {
|
||||
row.push({ value: '', className: 'nextMonth' })
|
||||
}else if(date_str > dnow ){
|
||||
row.push({ value: date_str, className: 'last', year: ynow, month: mnow, day: date_str})
|
||||
}else{
|
||||
row.push({ value: idx - firstday + 1, className: '', year: ynow, month: mnow, day: date_str})
|
||||
}
|
||||
}else{
|
||||
if(date_str > m_days[mnow-1]) {
|
||||
row.push({ value: '', className: 'nextMonth' })
|
||||
}else if(date_str > dnow ){
|
||||
row.push({ value: date_str, className: '', year: ynow, month: mnow, day: date_str})
|
||||
}else{
|
||||
row.push({ value: date_str, className: '', year: ynow, month: mnow, day: date_str})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理下月候补日期
|
||||
let list = row.reduce((arr,item,index)=>{
|
||||
if(item.className == 'nextMonth'){
|
||||
if(arr[index-1].value == m_days[mnow-1]){
|
||||
item.value = 1
|
||||
}else{
|
||||
item.value = arr[index-1].value + 1
|
||||
}
|
||||
}
|
||||
// 判断是否为当日
|
||||
item.className !== 'nextMonth' && item.year == year && item.month == month && item.day == day && (item.active = 'thatDay')
|
||||
item.className !== 'nextMonth' && item.year == year && item.month == month && item.day == day && (item.className = 'active')
|
||||
|
||||
// 处理需要打卡标记
|
||||
if(item.year && item.month && item.day){
|
||||
let nowDate = `${item.year}/${item.month}/${item.day}`
|
||||
let timer = new Date(nowDate).getTime().toString()
|
||||
successArr.includes(timer) && (item.tag = 'border')
|
||||
errorArr.includes(timer) && (item.tag = 'error')
|
||||
}
|
||||
arr.push(item)
|
||||
return arr
|
||||
},[])
|
||||
|
||||
arr.push({list, open: false})
|
||||
}
|
||||
|
||||
// 处理默认折叠状态
|
||||
arr.forEach((parent,index)=>{
|
||||
if(fold){
|
||||
parent.open = true
|
||||
}else{
|
||||
parent.open = parent.list.reduce((result, child)=>{
|
||||
if(ynow == year && mnow == month){
|
||||
child.value == dnow && child.className !== 'nextMonth' && (result = true)
|
||||
}else{
|
||||
index == 0 && (result = true)
|
||||
}
|
||||
return result
|
||||
}, false)
|
||||
}
|
||||
})
|
||||
return arr
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.punch-calendar-wrapper {
|
||||
.flex-center{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.flex-end{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.flex-start{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.flex-bt{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.calendar {
|
||||
width: 686rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 10rpx 25rpx rgba(0,0,0,0.1);
|
||||
.center {
|
||||
.week {
|
||||
padding-top: 32rpx;
|
||||
|
||||
.items {
|
||||
font-size: 32rpx;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #8c8f94;
|
||||
line-height: 32rpx;
|
||||
width: 98rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.day {
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.items {
|
||||
font-size: 32rpx;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #8c8f94;
|
||||
line-height: 32rpx;
|
||||
text-align: center;
|
||||
padding-top: 24rpx;
|
||||
padding-bottom: 32rpx;
|
||||
width: 98rpx;
|
||||
position: relative;
|
||||
|
||||
&.border ::before {
|
||||
content: '';
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
background: #b6d1ff;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
bottom: 10rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.error::before {
|
||||
content: '';
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
background: #ff5040;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
bottom: 10rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
text {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
display: block;
|
||||
transition: all 0.6s;
|
||||
border-radius: 32rpx;
|
||||
text-align: center;
|
||||
line-height: 48rpx;
|
||||
color: #474a50;
|
||||
|
||||
&.last,
|
||||
&.nextMonth {
|
||||
color: #c0c3c7;
|
||||
}
|
||||
|
||||
&.thatDay {
|
||||
background: #e6efff !important;
|
||||
color: #474a50;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #0D67FF !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
width: 100%;
|
||||
height: 78rpx;
|
||||
border-top: 1px solid #e6efff;
|
||||
|
||||
.icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
transition: all 0.6s;
|
||||
|
||||
&.active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top {
|
||||
width: 100%;
|
||||
height: 112rpx;
|
||||
border-bottom: 2px solid #e6efff;
|
||||
text {
|
||||
font-size: 32rpx;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
line-height: 32rpx;
|
||||
}
|
||||
.prev,
|
||||
.next {
|
||||
width: 100rpx;
|
||||
height: 100%;
|
||||
.icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"id": "punch-calendar",
|
||||
"displayName": "punch-calendar 打卡日历 可在日历标记圆点,配置简单,长期维护",
|
||||
"version": "1.0.6",
|
||||
"description": "打卡日历,可在日历标记圆点,配置简单,长期维护。",
|
||||
"keywords": [
|
||||
"punch-calendar"
|
||||
],
|
||||
"repository": "https://github.com/LonJinUp/punch-calendar",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.6.10"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "n",
|
||||
"vue3": "n"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "n",
|
||||
"app-nvue": "n"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "n",
|
||||
"Android Browser": "n",
|
||||
"微信浏览器(Android)": "n",
|
||||
"QQ浏览器(Android)": "n"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "n",
|
||||
"IE": "n",
|
||||
"Edge": "n",
|
||||
"Firefox": "n",
|
||||
"Safari": "n"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y",
|
||||
"钉钉": "y",
|
||||
"快手": "y",
|
||||
"飞书": "y",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
# punch-calendar
|
||||
|
||||
> [punch-calendar](https://github.com/LonJinUp/punch-calendar)为有打卡需求制作的日历,可标记小圆点。简单配置即可使用,代码体积小,无第三方引用。
|
||||
> 任何问题可以评论联系我,第一时间处理,或者添加 🛰️:ljsw8686
|
||||
|
||||
## 使用方法
|
||||
|
||||
demo:
|
||||
```html
|
||||
<template>
|
||||
<view class="content">
|
||||
<punch-calendar @switchMonth="switchMonth" @chooseDay="chooseDay" :errorList="errorList" :successList="successList" ref="calendar"></punch-calendar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
successList: ['1676995200000'],
|
||||
errorList: ['1676908800000'],
|
||||
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化
|
||||
this.$refs.calendar.initCalendar()
|
||||
|
||||
// 模拟异步赋值
|
||||
let timer = setTimeout(()=>{
|
||||
this.addTimer()
|
||||
},2000)
|
||||
|
||||
},
|
||||
methods: {
|
||||
// 点击某一天
|
||||
chooseDay(val) {
|
||||
console.log(val)
|
||||
},
|
||||
|
||||
addTimer() {
|
||||
this.successList = [...this.successList, '1681920000000']
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换事件
|
||||
* @param type 切换类型 prev next
|
||||
* @param nowYear 当前年
|
||||
* @param nowMonth 当前月
|
||||
* **/
|
||||
switchMonth(type, nowYear, nowMonth){
|
||||
//... doSomeThing
|
||||
if(nowYear == '2023' && nowMonth == '3' && !this.successList.includes('1678204800000')){
|
||||
uni.showLoading({})
|
||||
let timer = setTimeout(()=>{
|
||||
uni.hideLoading()
|
||||
clearTimeout(timer)
|
||||
this.successList = [...this.successList, '1678204800000']
|
||||
},3000)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 配置说明:
|
||||
|
||||
参数说明:
|
||||
|
||||
| 参数 | 说明 | 默认值 | 类型 |
|
||||
| ----------- | ---------------------------- | ------ | ----- |
|
||||
| successList | 打卡成功标记,传入13位时间戳 | [] | Array |
|
||||
| errorList | 打卡异常标记,传入13位时间戳 | [] | Array |
|
||||
|
||||
|
||||
回调方法
|
||||
|
||||
| 方法名称 | 说明 | 返回值 |
|
||||
| ---------- | -------------------- | ---------------------------- |
|
||||
| @chooseDay | 点击某日时候执行函数 | 返回一个对象,包含年、月、日 |
|
||||
| @switchMonth | 切换日期时候执行 | 返回type(切换类型,prev||next), 当前年nowYear,当前月nowMonth |
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 271 B |
Binary file not shown.
|
After Width: | Height: | Size: 262 B |
Binary file not shown.
|
After Width: | Height: | Size: 166 B |
Binary file not shown.
|
After Width: | Height: | Size: 168 B |
Loading…
Reference in New Issue