master
271556543@qq.com 4 years ago
parent 304dd489bb
commit 9d1a68b05f

5
.idea/.gitignore vendored

@ -0,0 +1,5 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

@ -1,11 +1,8 @@
const mode = 'devOnline'; //devLocal本地测试、devOnline线上测试、production生产环境
const mode = 'development';
let ROOTPATH = ''; //域名
switch (mode) {
case 'devLocal':
ROOTPATH = ""
break;
case 'devOnline':
ROOTPATH = ""
case 'development':
ROOTPATH = "http://sstt.ali251.langye.net"
break;
case 'production':
ROOTPATH = ""

@ -1,23 +1,51 @@
//api集合
let apiApp = {
login: '/api/login',
getInfo: '/777/777/index',
}
let apiHome = {
hotSearchUrl: '/777/77/hot_search'
}
let apiAuth = {
login: "/api/nurse/auth/login",
me: "/api/nurse/auth/me",
logout: "/api/nurse/auth/logout",
save: "/api/nurse/auth/save",
};
let apiTask = {
nurseList: "/api/nurse/nurse-list",
nurseDetail: "/api/nurse/nurse-detail",
nurseSave: "/api/nurse/nurse-save",
nurseCalendar: "/api/nurse/nurse-calendar",
noticeList: "/api/nurse/notice-list",
noticeDetail: "/api/nurse/notice-detail",
statistic: "/api/nurse/statistic",
};
// 此处第二个参数vm就是我们在页面使用的this你可以通过vm获取vuex等操作
const install = (Vue, vm) => {
//api方法
let login = (data = {}) => vm.$u.post(apiAuth.login, data);
let me = (data = {}) => vm.$u.post(apiAuth.me, data);
let logout = (data = {}) => vm.$u.post(apiAuth.logout, data);
let save = (data = {}) => vm.$u.post(apiAuth.save, data);
//api方法
let getSearch = (params = {}) => vm.$u.get(apiHome.hotSearchUrl, params);
let getInfo = (params={}) => vm.$u.post(apiApp.getInfo, params);
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
vm.$u.api = {getSearch, getInfo};
}
let nurseList = (params = {}) => vm.$u.get(apiTask.nurseList, params);
let nurseDetail = (params = {}) => vm.$u.get(apiTask.nurseDetail, params);
let nurseSave = (data = {}) => vm.$u.post(apiTask.nurseSave, data);
let nurseCalendar = (params = {}) => vm.$u.get(apiTask.nurseCalendar, params);
let noticeList = (params = {}) => vm.$u.get(apiTask.noticeList, params);
let noticeDetail = (params = {}) => vm.$u.get(apiTask.noticeDetail, params);
let statistic = (params = {}) => vm.$u.get(apiTask.statistic, params);
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
vm.$u.api = {
login,
me,
logout,
save,
nurseList,
nurseDetail,
nurseSave,
nurseCalendar,
noticeList,
noticeDetail,
statistic
};
};
export default {
install
}
install,
};

@ -1,4 +1,6 @@
import { ROOTPATH as baseUrl } from "@/common/config.js"
import {
ROOTPATH as baseUrl
} from "@/common/config.js"
// 这里的Vue为Vue对象(非创建出来的实例)vm为main.js中“Vue.use(httpInterceptor, app)”这一句的第二个参数,
// 为一个Vue的实例也即每个页面的"this"
@ -11,7 +13,7 @@ const install = (Vue, vm) => {
loadingMask: true, // 展示loading的时候是否给一个透明的蒙层防止触摸穿透
loadingText: '加载中', // 请求loading中的文字提示
loadingTime: 800,
originalData: false, // 是否在拦截器中返回服务端的原始数据
originalData: true, // 是否在拦截器中返回服务端的原始数据
// 设置自定义头部content-type
header: {
'content-type': 'application/json;charset=UTF-8'
@ -24,21 +26,10 @@ const install = (Vue, vm) => {
// 引用token
// 方式一存放在vuex的token假设使用了uView封装的vuex方式
// 见https://uviewui.com/components/globalVariable.html
config.header.token = vm.vuex_token;
// 方式二如果没有使用uView封装的vuex方法那么需要使用$store.state获取
// config.header.token = vm.$store.state.token;
// 方式三如果token放在了globalData通过getApp().globalData获取
// config.header.token = getApp().globalData.username;
// 方式四如果token放在了Storage本地存储中拦截是每次请求都执行的
// 所以哪怕您重新登录修改了Storage下一次的请求将会是最新值
// const token = uni.getStorageSync('token');
// config.header.token = token;
if(vm.vuex_token){
config.header['Authorization'] = `Bearer ${vm.vuex_token}`;
}
// 可以对某个url进行特别处理此url参数为this.$u.get(url)中的url值
if (config.url == '/test/jam') config.header.noToken = true;
// 最后需要将config进行return
return config;
// 如果return一个false值则会取消本次请求
@ -47,23 +38,28 @@ const install = (Vue, vm) => {
// 响应拦截,如配置,每次请求结束都会执行本方法
Vue.prototype.$u.http.interceptor.response = (res) => {
console.log('res-http',res)
if (res.code == 200) {
// res为服务端返回值可能有coderesult等字段
// 这里对res.result进行返回将会在this.$u.post(url).then(res => {})的then回调中的res的到
// 如果配置了originalData为true请留意这里的返回值
return res.result;
} else if (res.code == 201) {
// 假设201为token失效这里跳转登录
// vm.$u.toast('验证失败,请重新登录');
// setTimeout(() => {
// // 此为uView的方法详见路由相关文档
// vm.$u.route('/pages/user/login')
// }, 1500)
return false;
console.log('res-http', res)
if (res.statusCode === 200) {
if (res.data.errcode === 40001) {
uni.showToast({
icon: "none",
title: "登陆过期,请重新登录"
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/login/login'
})
}, 1500)
}
return res.data;
} else {
// 如果返回false则会调用Promise的reject回调
// 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中res为服务端的返回值
uni.showToast({
icon: "fail",
title: res.statusCode
})
return false;
}
}

@ -1,5 +1,29 @@
/*
* 公共方法
*
*/
* 公共方法
*
*/
//时间
export function formatDate(date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
};
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + '';
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
}
}
return fmt;
};
function padLeftZero(str) {
return ('00' + str).substr(str.length);
};

File diff suppressed because it is too large Load Diff

@ -4,22 +4,25 @@
<view>
<!-- 用户信息 -->
<view class="user-info">
<view class="user-info" v-if="detail.customer">
<view class="top">
<view class="left">
<u-image src="/static/logo.png" width="104" height="104" shape="circle"></u-image>
</view>
<view class="center">
<view class="name">余美君</view>
<view class="name">{{detail.customer.name}}</view>
<view class="infos">
<view class="age">74</view>
<view class="sex"></view>
<view class="age">{{ageComputed(detail.customer.birthday)}}
</view>
<view class="sex">{{detail.customer.sex}}</view>
<view class="organ">机构护理</view>
</view>
</view>
<view class="right">
<view class="icon3"></view>
<view>进行中</view>
<template v-if="detail.status === 1">
<view class="icon3"></view>
<view>进行中</view>
</template>
</view>
</view>
@ -28,7 +31,7 @@
<view class="bottom">
<view class="client">
<u-icon name="/static/detail/people.png" width="26" height="26"></u-icon>
<view>委托人余夏秀</view>
<view>委托人{{detail.customer.contact_name}}</view>
</view>
<view class="address">
<u-icon name="map" width="28" height="28" color="#1479FF"></u-icon>
@ -36,7 +39,7 @@
</view>
<view class="phone">
<u-icon name="phone" width="28" height="28" color="#1479FF"></u-icon>
<view>158****5455</view>
<view>{{detail.customer.phone}}</view>
</view>
</view>
<view class="re-location">
@ -54,39 +57,13 @@
<view class="line"></view>
<view class="content">
<view class="content-item">
<view class="content-item" v-for="(item,index) in detail.product.product_skus" :key='item.id'>
<view class="checkbox">
<u-checkbox v-model="form.handClean.isSelect" shape="circle"></u-checkbox>
<view>足部清洁</view>
<u-checkbox v-model="form[index].isSelect" shape="circle"></u-checkbox>
<view>{{item.sku_id}}</view>
</view>
<view class="input">
<u-input v-model="form.handClean.time" :custom-style="inputStyle" placeholder="请输入"
placeholder-style="color:#A7AFBC;" input-align="center" :clearable="false" type="number"
height="40">
</u-input>
<view>分钟</view>
</view>
</view>
<view class="content-item">
<view class="checkbox">
<u-checkbox v-model="form.mouthClean.isSelect" shape="circle"></u-checkbox>
<view>口腔清洁</view>
</view>
<view class="input">
<u-input v-model="form.mouthClean.time" :custom-style="inputStyle" placeholder="请输入"
placeholder-style="color:#A7AFBC;" input-align="center" :clearable="false" type="number"
height="40">
</u-input>
<view>分钟</view>
</view>
</view>
<view class="content-item">
<view class="checkbox">
<u-checkbox v-model="form.bedClean.isSelect" shape="circle"></u-checkbox>
<view>整理床单元</view>
</view>
<view class="input">
<u-input v-model="form.bedClean.time" :custom-style="inputStyle" placeholder="请输入"
<u-input v-model="form[index].time" :custom-style="inputStyle" placeholder="请输入"
placeholder-style="color:#A7AFBC;" input-align="center" :clearable="false" type="number"
height="40">
</u-input>
@ -102,52 +79,101 @@
<view class="text1">过程打卡</view>
<view class="text2">1</view>
</view>
<view class="btn">
<view class="btn" @click="locate">
<view class="text1">更新定位</view>
<view class="text2">05:19:34</view>
<view class="text2">{{$u.timeFormat(time,'hh:MM:ss')}}</view>
</view>
</view>
<!-- 打卡信息 -->
<view class="clock-info">
定位时间05:19:49 江苏省常州市天宁雕庄街道清扬中路辅路彩铃公寓
<view class="clock-info" v-if="location.lat && location.lng && location.time">
定位时间{{$u.timeFormat(location.time,'hh:MM:ss')}} {{location.address}}
</view>
</view>
</view>
</template>
<script>
import QQMapWX from '@/libs/qqmap-wx-jssdk.js'
export default {
data() {
return {
qqmapsdk: null,
inputStyle: {
fontSize: "24rpx",
color: "#36596A",
width: "140rpx",
background: "#F9F9F9"
},
form: {
handClean: {
isSelect: false,
time: null
},
mouthClean: {
isSelect: false,
time: null
},
bedClean: {
isSelect: false,
time: null
}
form: [],
detail: {},
time: new Date(),
location: {
lng: '',
lat: '',
time: '',
address: ''
}
}
},
methods: {
load() {
this.qqmapsdk = new QQMapWX({
key: 'D5EBZ-C3BWP-HZIDG-VO6BE-P2MN5-ESFZO'
});
},
async getDeatil(id) {
let res = await this.$u.api.nurseDetail({
id
})
this.detail = res
this.form = res.product.product_skus.map(item => {
return {
isSelect: false,
time: ''
}
})
},
//
locate() {
this.$u.throttle(() => {
uni.getLocation().then(res => {
this.location.lat = res[1]?.latitude
this.location.lng = res[1]?.longitude
this.location.time = this.time
this.qqmapsdk.reverseGeocoder({
location: {
latitude: this.location.lat,
longitude: this.location.lng
},
success: (r) => {
this.location.address = r.result.address
}
})
})
}, 5000)
},
},
computed: {
ageComputed() {
return function(birth) {
return new Date().getFullYear() - new Date(birth).getFullYear()
}
}
},
onLoad(option) {
this.load()
this.getDeatil(option.id)
setInterval(() => {
this.time = new Date()
}, 1000)
}
}
</script>

@ -3,11 +3,11 @@
<!-- 用户信息 -->
<view class="user-info" @click="toSetting">
<view class="head-img">
<u-avatar src="/static/logo.png" size="104"></u-avatar>
<u-avatar :src="vuex_user.avatar || '/static/logo.png'" size="104"></u-avatar>
</view>
<view class="name">
您好,XXX
您好,{{ vuex_user.name }}
</view>
</view>
@ -130,7 +130,7 @@
<scroll-view :scroll-y="true" style="height: 320rpx;">
<view class="info-list">
<view v-for="(item,inedx) in infoList" :key="index" class="info-item">
<view v-for="(item,index) in infoList" :key="index" class="info-item">
<view class="info-icon">
<u-image src="/static/home/chat.png" height="40" width="40"></u-image>
</view>
@ -197,11 +197,19 @@
url: "/pages/setting/setting"
})
})
},
async getStatistic() {
let res = await this.$u.api.statistic()
console.log(res);
}
},
computed: {
},
onShow() {
this.getStatistic()
}
}
</script>

@ -15,74 +15,87 @@
<!-- 下拉菜单 -->
<view class="drop-down">
<u-dropdown>
<u-dropdown-item title="状态" :options="options2"></u-dropdown-item>
<u-dropdown-item title="性别" :options="options2"></u-dropdown-item>
<u-dropdown-item title="时间" :options="options2"></u-dropdown-item>
<u-dropdown @open="calendarShow" @close="calendarHide">
<u-dropdown-item v-model="select.status" title="状态" :options="optionsStatus" @change='getList()'>
</u-dropdown-item>
<u-dropdown-item v-model="select.sex" title="性别" :options="optionsSex" @change="getList()">
</u-dropdown-item>
<u-dropdown-item title="时间">
</u-dropdown-item>
</u-dropdown>
</view>
<!-- 护理列表 -->
<view class="nursing-list">
<view v-for="(item,index) in nursingList" :key="index" class="list-item">
<view class="top">
<view class="time">{{item.time}}</view>
<view class="status">
<view class="status-icon"
:class="{icon1:item.status === 0,icon2:item.status === 1,icon3:item.status === 2}">
<view v-if="nursingList && nursingList.length > 0">
<view v-for="(item,index) in nursingList" :key="index" class="list-item">
<view class="top">
<view class="time">{{item.start_time}}</view>
<view class="status">
<view class="status-icon"
:class="{icon1:item.status === 0,icon2:item.status === 1,icon3:item.status === 2}">
</view>
<view v-if="item.status === 2" class="status-text"></view>
<view v-else-if="item.status === 0" class="status-text">待护理</view>
<view v-else class="status-text">已完成</view>
</view>
<view v-if="item.status === 2" class="status-text"></view>
<view v-else-if="item.status === 0" class="status-text">待护理</view>
<view v-else class="status-text">已完成</view>
</view>
</view>
<view class="line"></view>
<view class="line"></view>
<view class="center">
<view class="avatar">
<u-image src="/static/logo.png" height="104" width="104" shape="circle"></u-image>
</view>
<view class="user-info">
<view class="name">{{item.name}}</view>
<view class="tel">
<view>
<u-icon name="phone" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{item.tel}}</view>
<view class="center">
<view class="avatar">
<u-image src="/static/logo.png" height="104" width="104" shape="circle"></u-image>
</view>
<view class="address">
<view>
<u-icon name="map" size="28" color="#1479FF"></u-icon>
<view class="user-info">
<view class="name">{{item.customer.name}}</view>
<view class="tel">
<view>
<u-icon name="phone" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{item.customer.phone}}</view>
</view>
<view class="address">
<view>
<u-icon name="map" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{item.customer.address}}</view>
</view>
<view class="text">{{item.address}}</view>
</view>
</view>
<view class="sex">
<view class="sex-text">
{{item.sex}}
<view class="sex">
<view class="sex-text">
{{item.customer.sex}}
</view>
</view>
</view>
</view>
<view class="bottom">
<view class="distance">
<view class="distance-icon">
<u-image src="/static/todayNursing/distance.png" height="42" width="42"></u-image>
<view class="bottom">
<view class="distance">
<view class="distance-icon">
<u-image src="/static/todayNursing/distance.png" height="42" width="42"></u-image>
</view>
<view class="distance-text">{{item.distance}}公里</view>
</view>
<view class="distance-text">{{item.distance}}</view>
</view>
<view class="to-there">
<view class="to-there-text">去那里</view>
<view class="to-there-icon">
<u-image src="/static/todayNursing/to-there.png" height="46" width="46"></u-image>
<view class="to-there">
<view class="to-there-text">去那里</view>
<view class="to-there-icon">
<u-image src="/static/todayNursing/to-there.png" height="46" width="46"></u-image>
</view>
</view>
</view>
</view>
</view>
<view v-else>
<u-empty></u-empty>
</view>
</view>
</view>
<u-loadmore :status="status" :load-text='loadText' @loadmore='select.page++,getList()' />
<u-calendar v-model="isShowCalendar" @change='datePick'></u-calendar>
</view>
</template>
@ -90,56 +103,95 @@
export default {
data() {
return {
isShowCalendar: false,
inputStyle: {
width: "600rpx",
fontSize: "28rpx",
fontWeight: "500"
},
options2: [{
label: '去冰',
optionsStatus: [{
label: '待护理',
value: 0,
},
{
label: '护理中',
value: 1,
},
{
label: '加冰',
label: '已护理',
value: 2,
},
],
nursingList: [{
time: "2022-06-25",
name: "冯美君",
tel: "158****5455",
address: "通园路666号地图通园路66号",
distance: "距您1.7km",
status: 2,
sex: "女"
},
{
time: "2022-06-25",
name: "冯美君",
tel: "158****5455",
address: "通园路666号地图通园路66号",
distance: "距您1.7km",
status: 0,
sex: "女"
optionsSex: [{
label: '男',
value: '男',
},
{
time: "2022-06-25",
name: "冯美君",
tel: "158****5455",
address: "通园路666号地图通园路66号",
distance: "距您1.7km",
status: 1,
sex: "男"
label: '女',
value: '女',
}
]
],
status: 'loadmore',
loadText: {
loadmore: '轻轻上拉或点击',
loading: '努力加载中',
nomore: '实在没有了'
},
nursingList: [],
select: {
page_size: 10,
page: 1,
sex: '',
date: '',
status: '',
lat: '',
lng: ''
},
}
},
methods: {
calendarShow(e) {
if (e === 2) {
this.isShowCalendar = true
}
},
calendarHide() {
this.isShowCalendar = false
},
datePick(e) {
this.select.date = e.result
this.getList()
},
async getList() {
let res = await this.$u.api.nurseList(this.select)
if (res.data.length > 0 && res.data) {
this.nursingList.push(...res.data)
this.status = 'loadmore'
} else {
this.status = 'nomore'
this.select.page--
}
},
},
computed: {
},
onShow() {
uni.getLocation().then(res => {
this.select.lat = res[1]?.latitude
this.select.lng = res[1]?.longitude
this.getList()
})
},
onReachBottom() {
this.select.page++
this.status = 'loading';
}
}
</script>

@ -11,18 +11,19 @@
<view class="username">
<view class="left-name">账户名</view>
<u-input placeholder="请输入账户名" :custom-style="inputStyle" :placeholder-style="placeholderStyle">
<u-input v-model="form.username" placeholder="请输入账户名" :custom-style="inputStyle"
:placeholder-style="placeholderStyle">
</u-input>
</view>
<view class="password">
<view class="left-name">密码</view>
<u-input placeholder="请输入密码" type="password" :custom-style="inputStyle"
<u-input v-model="form.password" placeholder="请输入密码" type="password" :custom-style="inputStyle"
:placeholder-style="placeholderStyle"></u-input>
</view>
<view class="save-state">
<view class="radio" @click="isRemeber =! isRemeber">
<view class="radio" @click="isRemeber = !isRemeber">
<u-icon name="checkbox-mark" color="#fff" size="28" v-show="isRemeber">
</u-icon>
</view>
@ -30,12 +31,10 @@
</view>
<view class="btn">
<u-button :custom-style="btnStyle" :ripple="true" :hair-line="false">登陆</u-button>
<u-button :custom-style="btnStyle" :ripple="false" :hair-line="false" @click="login"></u-button>
</view>
<view class="bottom">
2022四世同堂服务有限公司
</view>
<view class="bottom"> 2022四世同堂服务有限公司 </view>
</view>
</view>
</template>
@ -52,7 +51,7 @@
flex: "1",
lineHeight: "40rpx",
fontSize: "28rpx",
fontWeight: "500"
fontWeight: "500",
},
btnStyle: {
color: "#fff",
@ -65,14 +64,40 @@
border: "none",
fontSize: "28rpx",
letterSpacing: "10rpx",
marginTop: "66rpx"
marginTop: "66rpx",
},
isRemeber: false
}
isRemeber: false,
form: {
username: "",
password: "",
},
};
},
methods: {},
computed: {}
}
methods: {
login() {
this.$u.api.login(this.form).then(res => {
this.$u.vuex("vuex_token", res.access_token);
this.getInfo();
})
},
getInfo() {
this.$u.api.me().then(res => {
this.$u.vuex("vuex_user", res);
uni.showToast({
icon: "none",
title: `欢迎回来,${res.name}`,
});
uni.switchTab({
url: "/pages/home/home"
});
})
},
},
computed: {},
};
</script>
<style scoped lang="scss">
@ -83,7 +108,7 @@
.login {
width: 100vw;
height: 100vh;
background: #187BFA;
background: #187bfa;
.bkg {
z-index: 0;
@ -94,12 +119,11 @@
}
.content {
z-index: 1;
position: relative;
.title {
color: #FFF;
color: #fff;
padding: 414rpx 0 60rpx 76rpx;
@ -120,7 +144,7 @@
font-weight: 500;
line-height: 46rpx;
padding-top: calc(576 - 414)rpx;
padding-top: calc(576 - 414) rpx;
}
}
@ -131,7 +155,7 @@
display: flex;
align-items: center;
background: #fff;
border: 2rpx solid #FFFEFE;
border: 2rpx solid #fffefe;
margin: 0 auto;
@ -151,7 +175,6 @@
.username {
@extend .input;
}
.password {
@ -171,7 +194,7 @@
width: 28rpx;
height: 28rpx;
border-radius: 6rpx;
border: 2rpx solid #FFFFFF;
border: 2rpx solid #ffffff;
display: flex;
justify-content: center;
align-items: center;
@ -183,7 +206,7 @@
font-size: 24rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #FFF;
color: #fff;
line-height: 34rpx;
margin-left: 30rpx;
@ -196,7 +219,7 @@
font-size: 24rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #FFFFFF;
color: #ffffff;
line-height: 34rpx;
margin: 418rpx auto 0 auto;

@ -7,8 +7,8 @@
<u-popup v-model="isShowPopup" mode="bottom" :mask="false" height="294rpx" :border-radius="40">
<view class="top">
<view class="left">
<view class="name">{{selectMarker.label.content}}</view>
<view class="sex"></view>
<view class="name">{{selectMarker.info.customer.name}}</view>
<view class="sex">{{selectMarker.info.customer.sex}}</view>
</view>
<view class="right">
<view class="icon icon3"></view>
@ -21,13 +21,13 @@
<view>
<u-icon name="phone" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">158****5455</view>
<view class="text">{{selectMarker.info.customer.phone}}</view>
</view>
<view class="address">
<view>
<u-icon name="map" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">通园路666号地图通园路66号</view>
<view class="text">{{selectMarker.info.customer.address}}</view>
</view>
</view>
@ -36,9 +36,9 @@
<view class="distance-icon">
<u-image src="/static/todayNursing/distance.png" height="42" width="42"></u-image>
</view>
<view class="distance-text">距您1.7km</view>
<view class="distance-text">{{selectMarker.info.distance}}公里</view>
</view>
<view class="to-there">
<view class="to-there" @click="toThere">
<view class="to-there-text">去那里</view>
<view class="to-there-icon">
<u-image src="/static/todayNursing/to-there.png" height="46" width="46"></u-image>
@ -59,15 +59,20 @@
longitude: null,
covers: []
},
iconMap: new Map([
[0, '/static/map/todo.png'],
[1, '/static/map/doing.png'],
[2, '/static/map/done.png'],
]),
isShowPopup: false,
selectMarker: null,
}
},
methods: {
async markertap(e) {
let marker = this.covers[e.detail.markerId - 1]
this.covers[e.detail.markerId - 1].height = 39
this.covers[e.detail.markerId - 1].width = 30
let marker = this.covers[e.detail.markerId]
this.covers[e.detail.markerId].height = 39
this.covers[e.detail.markerId].width = 30
this.covers.map(item => {
if (item.id != marker.id) {
item.width = 20
@ -129,101 +134,26 @@
})
},
getCovers() {
this.covers = [{
id: 1,
latitude: 31.26000,
longitude: 120.63000,
width: 14,
height: 18,
iconPath: '/static/map/doing.png',
joinCluster: true,
label: {
content: "冯晓梅",
fontSize: 14,
color: '#36596A',
width: 54,
height: 25,
bgColor: '#FFFFFF',
borderRadius: 5,
textAlign: 'center',
anchorX: -7,
anchorY: 0,
}
},
{
id: 2,
latitude: 31.26044,
longitude: 120.63013,
width: 14,
height: 18,
iconPath: '/static/map/done.png',
joinCluster: true,
label: {
content: "项小北",
fontSize: 14,
color: '#36596A',
width: 54,
height: 25,
bgColor: '#FFFFFF',
borderRadius: 5,
textAlign: 'center',
anchorX: -7,
anchorY: 0,
}
},
{
id: 3,
latitude: 31.24998,
longitude: 120.63007,
width: 14,
height: 18,
iconPath: '/static/map/done.png',
joinCluster: true,
label: {
content: "冯晓梅",
fontSize: 14,
color: '#36596A',
width: 54,
height: 25,
bgColor: '#FFFFFF',
borderRadius: 5,
textAlign: 'center',
anchorX: -7,
anchorY: 0,
}
},
{
id: 4,
latitude: 31.23451,
longitude: 120.62768,
width: 14,
height: 18,
iconPath: '/static/map/todo.png',
joinCluster: true,
label: {
content: "项小北",
fontSize: 14,
color: '#36596A',
width: 54,
height: 25,
bgColor: '#FFFFFF',
borderRadius: 5,
textAlign: 'center',
anchorX: -7,
anchorY: 0,
}
},
{
id: 5,
latitude: 31.26014,
longitude: 120.63066,
async getCovers() {
let res = await this.$u.api.nurseList({
page: 1,
page_size: 999,
date: `${new Date().getFullYear()}-${new Date().getMonth()+1}-${new Date().getDate()}`,
lat: this.location.latitude,
lng: this.location.longitude
})
console.log(res);
this.covers = res.data.map((item, index) => {
return {
id: index,
latitude: Number(item.customer.lat),
longitude: Number(item.customer.lng),
width: 14,
height: 18,
iconPath: '/static/map/todo.png',
iconPath: this.iconMap.get(item.status),
joinCluster: true,
label: {
content: "冯晓梅",
content: item.customer.name,
fontSize: 14,
color: '#36596A',
width: 54,
@ -233,23 +163,34 @@
textAlign: 'center',
anchorX: -7,
anchorY: 0,
}
},
info: item
}
]
})
this.mapCtx.addMarkers({
markers: this.covers,
clear: false,
complete: (res) => {}
})
},
toThere() {
this.$u.throttle(() => {
uni.openLocation({
latitude: this.selectMarker.latitude,
longitude: this.selectMarker.longitude,
name: this.selectMarker.info.customer.address
})
})
}
},
computed: {
},
onLoad() {
this.getNowLocation()
},
async onReady() {
await this.getNowLocation()
this.mapCtx = uni.createMapContext("map", this)
this.mapCtx.initMarkerCluster({
enableDefaultStyle: false,
@ -260,7 +201,7 @@
this.updateClusters(e.clusters)
})
this.getCovers()
await this.getCovers()
}
}
</script>
@ -382,12 +323,10 @@
}
.distance-text {
height: 34rpx;
font-size: 24rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #A7AFBC;
line-height: 34rpx;
padding-left: 20rpx;
}

@ -42,7 +42,7 @@
<view class="canlendar">
<view v-for="(row,index) in calendar" :key="index" class="row">
<view v-for="(date,index1) in row" :key="index1" @click="dateClick(date,index1)" class="item"
:class="{itemOver:date.type === -1||date.type === 1||date.type === 2,itemActive:date.date === dateIndex&&date.type === 0}">
:class="{itemOver:date.type === -1||date.type === 1||date.type === 2,itemActive:date.date === select.date&&date.type === 0}">
{{date.date}}
<view class="icon icon1" v-if="dateIn(date.date) === 0&&date.type === 0"></view>
<view class="icon icon2" v-if="dateIn(date.date) === 2&&date.type === 0"></view>
@ -69,34 +69,39 @@
<!-- 选中护理当日信息 -->
<view class="select-info">
<view class="selet-date">
{{select.year}}-{{select.month}}-{{dateIndex}}
{{select.year}}{{select.month}}{{select.date}}
</view>
<view class="select-day">
{{getDay(select.year+"/"+select.month+"/"+dateIndex)}}
{{getDay(select.year+"/"+select.month+"/"+select.date)}}
</view>
</view>
<!-- 选中当日护理人员 -->
<view class="select-user-list">
<scroll-view :scroll-y="true" style="height: 520rpx;">
<view v-for="(item,index) in selectUserList" :key="index" class="user-item">
<view class="left">
<u-image src="/static/logo.png" height="104" width="104" shape="circle"></u-image>
</view>
<view class="center">
<view class="top">{{item.name}}</view>
<view class="bottom">
<view class="time">{{item.time}}</view>
<view class="list-status-icon"
:class="{icon1:item.status === 0,icon2:item.status === 1,icon3:item.status === 2}">
<scroll-view :scroll-y="true" style="height: 520rpx;position: relative;">
<view v-if="selectUserList && selectUserList.length > 0">
<view v-for="(item,index) in selectUserList" :key="index" class="user-item">
<view class="left">
<u-image src="/static/logo.png" height="104" width="104" shape="circle"></u-image>
</view>
<view class="center">
<view class="top">{{item.customer.name}}</view>
<view class="bottom">
<view class="time">{{$u.timeFormat(new Date(item.start_time),'hh:MM')}}</view>
<view class="list-status-icon"
:class="{icon1:item.status === 0,icon2:item.status === 2,icon3:item.status === 1}">
</view>
<view class="list-status-text">{{formatStatus(item.status)}}</view>
</view>
<view class="list-status-text">{{formatStatus(item.status)}}</view>
</view>
</view>
<view class="right">
<u-icon name="arrow-right" size="22"></u-icon>
<view class="right" @click="toDetail(item)">
<u-icon name="arrow-right" size="22"></u-icon>
</view>
</view>
</view>
<view v-else style="position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);">
<u-empty></u-empty>
</view>
</scroll-view>
</view>
</view>
@ -104,6 +109,9 @@
</template>
<script>
import {
formatDate
} from 'common/util.js'
export default {
data() {
return {
@ -136,10 +144,11 @@
//
select: {
year: new Date().getFullYear(),
month: new Date().getMonth() + 1
month: new Date().getMonth() + 1,
date: new Date().getDate()
},
//
dateIndex: new Date().getDate(),
//dateIndex: new Date().getDate(),
calendar: '',
params: {
year: true,
@ -149,22 +158,16 @@
minute: false,
second: false
},
selectUserList: [{
name: "王新",
time: "09:00",
status: 2
},
{
name: "王新",
time: "09:00",
status: 0
},
{
name: "王新",
time: "09:00",
status: 1
},
]
selectUserList: [],
//
selector: {
page_size: 999,
page: 1,
date: '',
lat: '',
lng: ''
}
}
},
methods: {
@ -191,7 +194,7 @@
},
dateClick(date, index1) {
if (date.type === 0) {
this.dateIndex = date.date
this.select.date = date.date
}
},
getCalendar(year, month) {
@ -277,7 +280,21 @@
type: -1
}])
this.calendar = res
}
},
async getList() {
let res = await this.$u.api.nurseList(this.selector)
this.selectUserList = res.data
},
toDetail(item) {
uni.$u.throttle(() => {
uni.navigateTo({
url: `/pages/detailNursing/detailNursing?id=${item.id}`
})
})
},
},
computed: {
getDay() {
@ -305,16 +322,25 @@
return "未知"
}
}
}
},
},
watch: {
select: {
handler(newVal, oldVal) {
this.getCalendar(this.select.year, this.select.month)
this.selector.date = `${this.select.year}-${this.select.month}-${this.select.date}`
this.getList()
},
immediate: true,
deep: true
}
},
onShow() {
uni.getLocation().then(res => {
this.selector.lat = res[1]?.latitude
this.selector.lng = res[1]?.longitude
})
}
}
</script>

@ -1,188 +1,207 @@
<template>
<view>
<cpn-navbar title="设置" :isBack="true"></cpn-navbar>
<view>
<!-- 个人信息 -->
<view class="user-info">
<view class="user-info-title">个人信息</view>
<view class="user-info-content">
<view class="head-img">
<view class="text">头像</view>
<view style="display: flex;">
<view class="avatar">
<u-image src="/static/logo.png" height="104" width="104" shape="circle"></u-image>
</view>
<view class="arrow">
<u-icon name="arrow-right" size="24"></u-icon>
</view>
</view>
</view>
<view class="line"></view>
<view class="name">
<view class="name-text">账户名</view>
<view class="name-user">王老师</view>
</view>
</view>
</view>
<!-- 版本信息 -->
<view class="sys-info">
<view class="sys-info-title">版本信息</view>
<view class="sys-info-content">
<view>当前版本</view>
<view>V2.0</view>
</view>
</view>
<view class="logout">
<u-button :hair-line="false" :custom-style="btnStyle">退出登录</u-button>
</view>
</view>
</view>
<view>
<cpn-navbar title="设置" :isBack="true"></cpn-navbar>
<view>
<!-- 个人信息 -->
<view class="user-info">
<view class="user-info-title">个人信息</view>
<view class="user-info-content">
<view class="head-img">
<view class="text">头像</view>
<view style="display: flex">
<view class="avatar">
<u-image
:src="vuex_user.avatar || '/static/logo.png'"
height="104"
width="104"
shape="circle"
></u-image>
</view>
<view class="arrow">
<u-icon name="arrow-right" size="24"></u-icon>
</view>
</view>
</view>
<view class="line"></view>
<view class="name">
<view class="name-text">账户名</view>
<view class="name-user">{{ vuex_user.name || "" }}</view>
</view>
</view>
</view>
<!-- 版本信息 -->
<view class="sys-info">
<view class="sys-info-title">版本信息</view>
<view class="sys-info-content">
<view>当前版本</view>
<view>V{{ vuex_version }}</view>
</view>
</view>
<view class="logout">
<u-button :hair-line="false" :custom-style="btnStyle" @click="logout"
>退出登录</u-button
>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
btnStyle: {
width: "670rpx",
height: "76rpx",
color: "#1479FF",
border: "2rpx solid #1479FF"
}
}
},
methods: {
},
computed: {
},
}
export default {
data() {
return {
btnStyle: {
width: "670rpx",
height: "76rpx",
color: "#1479FF",
border: "2rpx solid #1479FF",
},
};
},
methods: {
logout() {
this.$u.api.logout().then((res) => {
uni.showToast({
title: res.msg,
icon: 'none'
})
setTimeout(()=>{
uni.navigateTo({
url: "/pages/login/login",
fail: (err) => {
console.log(err);
},
});
uni.clearStorageSync();
},1500)
});
},
},
computed: {},
};
</script>
<style scoped lang="scss">
.user-info {
margin-top: 28rpx;
&-title {
height: 40rpx;
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #ABAEBE;
line-height: 40rpx;
padding-left: 40rpx;
}
&-content {
width: 750rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(219, 218, 218, 0.5);
margin: 26rpx auto 0 auto;
.head-img {
display: flex;
justify-content: space-between;
align-items: center;
&>view>view {
align-self: center;
}
.text {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
padding-left: 40rpx;
}
.avatar {
padding: 18rpx 0rpx;
}
.arrow {
padding: 0 50rpx 0 40rpx;
}
}
.line {
width: 670rpx;
height: 2rpx;
border: 2rpx solid #EEEFF5;
margin: 0 auto;
}
.name {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 40rpx;
&-text {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
}
&-user {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
}
}
}
}
.sys-info {
margin-top: 34rpx;
&-title {
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #ABAEBE;
padding: 0 0 26rpx 36rpx;
}
&-content {
background: #FFFFFF;
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(219, 218, 218, 0.5);
display: flex;
justify-content: space-between;
align-items: center;
padding: 22rpx 40rpx;
&>view {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
}
}
}
.logout {
margin-top: 40rpx;
}
.user-info {
margin-top: 28rpx;
&-title {
height: 40rpx;
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #abaebe;
line-height: 40rpx;
padding-left: 40rpx;
}
&-content {
width: 750rpx;
background: #ffffff;
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(219, 218, 218, 0.5);
margin: 26rpx auto 0 auto;
.head-img {
display: flex;
justify-content: space-between;
align-items: center;
& > view > view {
align-self: center;
}
.text {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
padding-left: 40rpx;
}
.avatar {
padding: 18rpx 0rpx;
}
.arrow {
padding: 0 50rpx 0 40rpx;
}
}
.line {
width: 670rpx;
height: 2rpx;
border: 2rpx solid #eeeff5;
margin: 0 auto;
}
.name {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 40rpx;
&-text {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
}
&-user {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
}
}
}
}
.sys-info {
margin-top: 34rpx;
&-title {
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #abaebe;
padding: 0 0 26rpx 36rpx;
}
&-content {
background: #ffffff;
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(219, 218, 218, 0.5);
display: flex;
justify-content: space-between;
align-items: center;
padding: 22rpx 40rpx;
& > view {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
}
}
}
.logout {
margin-top: 40rpx;
}
</style>

@ -11,62 +11,68 @@
</view>
<view class="nursing-list">
<view v-for="(item,index) in nursingList" :key="index" class="list-item">
<view class="top">
<view class="time">{{item.time}}</view>
<view class="status">
<view class="status-icon"
:class="{icon1:item.status === 0,icon2:item.status === 1,icon3:item.status === 2}">
<view v-if="nursingList && nursingList.length > 0">
<view v-for="(item,index) in nursingList" :key="item.id" class="list-item" @click="toDetail(item)">
<view class="top">
<view class="time">{{item.start_time}}</view>
<view class="status">
<view class="status-icon"
:class="{icon1:item.status === 0,icon2:item.status === 2,icon3:item.status === 1}">
</view>
<view v-if="item.status === 1" class="status-text"></view>
<view v-else-if="item.status === 0" class="status-text">待护理</view>
<view v-else class="status-text">已完成</view>
</view>
<view v-if="item.status === 2" class="status-text"></view>
<view v-else-if="item.status === 0" class="status-text">待护理</view>
<view v-else class="status-text">已完成</view>
</view>
</view>
<view class="line"></view>
<view class="line"></view>
<view class="center">
<view class="avatar">
<u-image src="/static/logo.png" height="104" width="104" shape="circle"></u-image>
</view>
<view class="user-info">
<view class="name">{{item.name}}</view>
<view class="tel">
<view>
<u-icon name="phone" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{item.tel}}</view>
<view class="center">
<view class="avatar">
<u-image src="/static/logo.png" height="104" width="104" shape="circle"></u-image>
</view>
<view class="address">
<view>
<u-icon name="map" size="28" color="#1479FF"></u-icon>
<view class="user-info">
<view class="name">{{item.customer.name}}</view>
<view class="tel">
<view>
<u-icon name="phone" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{item.customer.phone}}</view>
</view>
<view class="address">
<view>
<u-icon name="map" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{item.customer.address}}</view>
</view>
<view class="text">{{item.address}}</view>
</view>
</view>
<view class="sex">
<view class="sex-text">
{{item.sex}}
<view class="sex">
<view class="sex-text">
{{item.customer.sex}}
</view>
</view>
</view>
</view>
<view class="bottom">
<view class="distance">
<view class="distance-icon">
<u-image src="/static/todayNursing/distance.png" height="42" width="42"></u-image>
<view class="bottom">
<view class="distance">
<view class="distance-icon">
<u-image src="/static/todayNursing/distance.png" height="42" width="42"></u-image>
</view>
<view class="distance-text">{{item.distance}}公里</view>
</view>
<view class="distance-text">{{item.distance}}</view>
</view>
<view class="to-there">
<view class="to-there-text">去那里</view>
<view class="to-there-icon">
<u-image src="/static/todayNursing/to-there.png" height="46" width="46"></u-image>
<view class="to-there">
<view class="to-there-text">去那里</view>
<view class="to-there-icon">
<u-image src="/static/todayNursing/to-there.png" height="46" width="46"></u-image>
</view>
</view>
</view>
</view>
</view>
<view v-else class="nursing-list-nodata">
<u-empty mode="data">
</u-empty>
</view>
</view>
</view>
@ -77,34 +83,15 @@
export default {
data() {
return {
nursingList: [{
time: "2022-06-25",
name: "冯美君",
tel: "158****5455",
address: "通园路666号地图通园路66号",
distance: "距您1.7km",
status: 2,
sex: "女"
},
{
time: "2022-06-25",
name: "冯美君",
tel: "158****5455",
address: "通园路666号地图通园路66号",
distance: "距您1.7km",
status: 0,
sex: "女"
},
{
time: "2022-06-25",
name: "冯美君",
tel: "158****5455",
address: "通园路666号地图通园路66号",
distance: "距您1.7km",
status: 1,
sex: "男"
}
]
select: {
page: 1,
page_size: 999,
date: `${new Date().getFullYear()}-${new Date().getMonth()+1}-${new Date().getDate()}`,
lat: '',
lng: ''
},
nursingList: []
}
},
methods: {
@ -115,11 +102,33 @@
url: "/pages/map/map"
})
})
},
//
toDetail(item) {
uni.$u.throttle(() => {
uni.navigateTo({
url: `/pages/detailNursing/detailNursing?id=${item.id}`
})
})
},
async getToday() {
let res = await this.$u.api.nurseList(this.select)
console.log(res);
this.nursingList = res.data
}
},
computed: {
},
onShow() {
uni.getLocation().then(res => {
this.select.lat = res[1]?.latitude
this.select.lng = res[1]?.longitude
this.getToday()
})
}
}
</script>
@ -343,5 +352,13 @@
}
}
}
&-nodata {
transform: translate(-50%, -50%);
position: fixed;
top: 50%;
left: 50%;
}
}
</style>

@ -30,7 +30,11 @@ const saveLifeData = function(key, value) {
const store = new Vuex.Store({
// 下面这些值仅为示例,使用过程中请删除
state: {
// 如果上面从本地获取的lifeData对象下有对应的属性就赋值给state中对应的变量
// 加上vuex_前缀是防止变量名冲突也让人一目了然
vuex_user: lifeData.vuex_user || null,
vuex_token: lifeData.vuex_token || '',
vuex_version: '1.0',
},
mutations: {
$uStore(state, payload) {
@ -52,6 +56,14 @@ const store = new Vuex.Store({
}
// 保存变量到本地,见顶部函数定义
saveLifeData(saveKey, state[saveKey])
},
logout(state) {
state.vuex_user = null
state.vuex_loginStatus = 0
state.vuex_token = null
uni.removeStorageSync("lifeData")
}
}
})

Loading…
Cancel
Save