You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

656 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view>
<cpn-navbar title="客户列表" :is-back="true"></cpn-navbar>
<view>
<view>
<u-button :custom-style="{'margin':'24rpx 24rpx 0 24rpx'}" type="warning" @click="refresh"></u-button>
</view>
<!-- 搜索同一行 -->
<view class="search-row">
<view class="search small">
<view class="input-content">
<u-input :clearable="false" :value="select.keyword" placeholder="关键词" height="30" :custom-style="inputStyle"
@input="searchInput"></u-input>
</view>
<view class="icon">
<u-icon name="search" size="46" color="#ABAEBE"></u-icon>
</view>
</view>
<view class="search small">
<view class="input-content">
<u-input :clearable="true" :value="select.village_name" placeholder="市/区/社区街道/镇/村" height="30" :custom-style="inputStyle"
@input="villageInput"></u-input>
</view>
<!-- <view class="icon">
<u-icon name="home" size="46" color="#ABAEBE"></u-icon>
</view> -->
</view>
</view>
<!-- 回访/生存状态 下拉同一行 -->
<view class="drop-down" style="padding: 0 24rpx;">
<u-dropdown>
<u-dropdown-item v-model="select.has_quality_callbacks" title="回访" :options="callbackDropdownOptions" />
<u-dropdown-item v-model="select.is_dead" title="状态" :options="deadDropdownOptions" />
</u-dropdown>
</view>
<!-- 产品类型 下拉 -->
<view class="drop-down" style="padding: 0 24rpx; margin-top: 16rpx;">
<u-dropdown>
<u-dropdown-item v-model="select.product_type_id" title="产品类型" :options="productTypeOptions" />
</u-dropdown>
</view>
<!-- 护理列表 -->
<view class="nursing-list">
<view v-if="nursingList && nursingList.length > 0">
<view v-for="(item,index) in nursingList" :key="index" class="list-item">
<view class="top">
<view v-if="item.quality_callbacks_count>0" @click="pageTo('/package_sub/pages/quality/qualityHistory?customer_id='+item.id)" class="time">
回访次数 <text style="color:#2979ff">{{ item.quality_callbacks_count }}</text> 次</view>
<view v-else class="time">回访次数 {{ 0 }} 次</view>
<view class="status">
<view class="status-text">{{ item.product_type_name }}</view>
</view>
</view>
<view class="line"></view>
<view class="center">
<view class="avatar">
<u-image :src="item.sex === '男' ? vuex_male_img : vuex_female_img" 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.phone || '无'}}</view>
</view>
<view class="address">
<view>
<u-icon name="map" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{defaultAddress(item.customer_address).address || '无'}}</view>
</view>
<view class="age">
<view>
<u-icon name="calendar" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">{{getAgeByIdcard(item.idcard) || '-'}}岁</view>
</view>
<view class="dislevel">
<view>
<u-icon name="eye-off" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">失能等级{{ item.level_type_detail ? item.level_type_detail.value : '' }} {{ item.level_detail ? item.level_detail.value : '' }}</view>
</view>
<view class="contact">
<view>
<u-icon name="man-add-fill" size="28" color="#1479FF"></u-icon>
</view>
<view class="text">联系人 {{ item.contact_name?item.contact_name:'' }}</view>
</view>
</view>
<view class="sex">
<view class="sex-text">
{{item.sex || '无'}}
</view>
</view>
</view>
<view class="bottom">
<u-button style="width: 90%;margin: 10rpx auto 0;"
type="primary"
ripple
@click="pageTo('/package_sub/pages/addQuality/addQuality?customer_id='+item.id+'&customer_name='+item.name)">质控回访</u-button>
</view>
</view>
</view>
<view v-else>
<u-empty mode="list" text="暂无记录"></u-empty>
</view>
</view>
</view>
<u-loadmore :status="status" :load-text='loadText' @loadmore='select.page++,getList()' />
<u-back-top :scroll-top="scrollTop"></u-back-top>
<!-- 附近客户 悬浮按钮 -->
<view class="nearby-fab" @click="fetchNearby">
<text class="nearby-fab-text">附近客户</text>
</view>
</view>
</template>
<script>
import { getAgeByIdcard } from "@/common/util";
export default {
data() {
return {
scrollTop: 0,
isShowCalendar: false,
inputStyle: {
width: "100%",
fontSize: "28rpx",
fontWeight: "500"
},
callbackDropdownOptions: [
{ label: '全部', value: 'all' },
{ label: '无回访', value: 0 },
{ label: '有回访', value: 1 },
],
deadDropdownOptions: [
{ label: '全部', value: 'all' },
{ label: '正常', value: 0 },
{ label: '死亡', value: 1 },
],
productTypeOptions: [
{ label: '全部', value: 'all' }
],
optionsStatus: [{
label: '全部',
value: ''
},
{
label: '待护理',
value: '0',
},
{
label: '护理中',
value: 1,
},
{
label: '已护理',
value: 2,
},
],
optionsSex: [{
label: '全部',
value: ''
},
{
label: '男',
value: '男',
},
{
label: '女',
value: '女',
},
],
status: 'loadmore',
loadText: {
loadmore: '轻轻上拉或点击',
loading: '努力加载中',
nomore: '实在没有了'
},
nursingList: [],
select: {
page_size: 10,
page: 1,
keyword: '',
village_name: '',
has_quality_callbacks: 'all',
is_dead: 'all',
lat: '',
lng: '',
product_type_id: 'all'
},
}
},
methods: {
getAgeByIdcard,
async loadProductTypes() {
try {
const res = await this.$u.api.adminProductTypeList({ page: 1, page_size: 99,sort_type:'desc',sort_name:'sortnumber' })
const list = (res && res.data && res.data.data) ? res.data.data : (res && res.data ? res.data : [])
this.productTypeOptions = [{ label: '全部', value: 'all' }].concat(
(list || []).map(it => ({ label: it.name, value: it.id }))
)
} catch (e) {
// ignore
}
},
refresh(){
this.select = {
page_size: 10,
page: 1,
keyword: '',
village_name: '',
has_quality_callbacks: 'all',
is_dead: 'all',
lat: '',
lng: '',
product_type_id: 'all'
}
this.nursingList = []
this.getList()
},
searchInput(e) {
this.select.keyword = e
this.nursingList = []
this.select.page = 1
this.$u.debounce(this.getList, 1000)
},
villageInput(e) {
this.select.village_name = e
this.nursingList = []
this.select.page = 1
this.$u.debounce(this.getList, 1000)
},
async fetchNearby() {
try {
const res = await uni.getLocation({ type: 'gcj02', isHighAccuracy: true })
// uni.getLocation Promise 风格返回 [err, data]
const location = Array.isArray(res) ? res[1] : res
if (location && location.latitude && location.longitude) {
this.select.lat = location.latitude
this.select.lng = location.longitude
this.nursingList = []
this.select.page = 1
this.getList()
} else {
uni.showToast({ icon: 'none', title: '定位失败,请稍后重试' })
}
} catch (e) {
uni.showToast({ icon: 'none', title: '未能获取定位权限' })
}
},
async getList() {
const params = { ...this.select }
if (params.has_quality_callbacks === 'all') params.has_quality_callbacks = ''
if (params.is_dead === 'all') params.is_dead = ''
if (params.product_type_id === 'all') params.product_type_id = ''
const response = await this.$u.api.adminCustomerList(params)
console.log("response",response)
let res = response.data
if (res.data.length > 0 && res.data) {
this.nursingList.push(...res.data)
this.status = 'loadmore'
} else {
this.status = 'nomore'
if (this.select.page > 1) {
this.select.page--
}
}
},
pageTo (url) {
uni.navigateTo({
url
})
}
},
computed: {
statusComputed() {
return function(status) {
switch (status) {
case '0':
return "待护理"
break;
case 1:
return "护理中"
break;
case 2:
return "已护理"
break;
default:
return '全部'
}
}
},
defaultAddress () {
return function (address) {
return address&&address.length>0?address[0]: {}
}
}
},
watch: {
'select.has_quality_callbacks'(val) {
this.nursingList = []
this.select.page = 1
this.getList()
},
'select.is_dead'(val) {
this.nursingList = []
this.select.page = 1
this.getList()
},
'select.product_type_id'(val) {
this.nursingList = []
this.select.page = 1
this.getList()
}
},
onReachBottom() {
this.select.page++
this.status = 'loading';
this.getList()
},
onShow() {
this.select.page = 1
this.nursingList = []
this.loadProductTypes()
this.getList()
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
}
}
</script>
<style scoped lang="scss">
//
/deep/.u-dropdown__menu {
justify-content: space-between !important;
}
/deep/.u-dropdown__menu__item {
width: 340rpx !important; //
flex: none !important;
height: 70rpx;
background: #FFFFFF;
border-radius: 10rpx;
justify-content: space-between !important;
}
/deep/.u-dropdown__menu__item .u-flex {
flex: 1;
}
/deep/.u-dropdown__menu__item__text {
flex: 1 !important;
font-size: 32rpx !important;
font-weight: 500 !important;
color: #333333 !important;
text-align: center;
padding: 12rpx 0rpx !important;
}
/deep/.u-dropdown__menu__item__arrow {
width: 70rpx !important;
height: 70rpx !important;
background: rgba(20, 121, 255, 0.1) !important;
border-radius: 10rpx !important;
border: 2rpx solid #FFFFFF !important;
display: flex;
justify-content: center;
align-items: center;
}
/deep/.u-load-more-wrap {
padding: 10px 0;
}
.search {
width: 710rpx;
height: 70rpx;
background: #FFFFFF;
border: 2rpx solid #FAFBFC;
display: flex;
align-items: center;
justify-content: space-between;
margin: 24rpx 24rpx 0 24rpx;
.input-content {
margin-left: 30rpx;
}
.icon {
margin-right: 30rpx;
}
}
.search-row {
width: 710rpx;
display: flex;
justify-content: space-between;
margin: 24rpx 24rpx 0 24rpx;
}
.search.small {
width: 340rpx;
margin: 0;
}
.drop-down {
margin-top: 20rpx;
}
.nursing-list {
margin-top: 10rpx;
.list-item {
width: 710rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(219, 218, 218, 0.5);
margin: 0 20rpx 26rpx 22rpx;
.top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 22rpx 0;
.time {
font-size: 32rpx;
font-weight: 500;
color: #36596A;
line-height: 32rpx;
padding-left: 20rpx;
}
.status {
display: flex;
align-items: center;
.status-icon {
margin-right: 10rpx;
}
.status-text {
height: 40rpx;
font-size: 28rpx;
font-weight: 500;
color: #36596A;
line-height: 40rpx;
margin-right: 20rpx;
}
}
}
.line {
width: 670rpx;
height: 2rpx;
border: 2rpx solid #EEEFF5;
margin: 0 auto;
}
.center {
display: flex;
justify-content: space-between;
padding-top: 24rpx;
.avatar {
padding-top: 4rpx;
padding-left: 20rpx;
}
.user-info {
flex: 1;
padding-left: 24rpx;
.name {
width: 270rpx;
height: 48rpx;
font-size: 32rpx;
font-weight: 500;
color: #333333;
}
.tel {
height: 40rpx;
font-size: 28rpx;
font-weight: 500;
color: #36596A;
line-height: 40rpx;
display: flex;
margin-top: 18rpx;
.text {
margin-left: 10rpx;
}
}
.address {
font-size: 28rpx;
font-weight: 500;
color: #36596A;
line-height: 40rpx;
display: flex;
margin-top: 14rpx;
.text {
margin-left: 10rpx;
}
}
}
.sex {
width: 40rpx;
height: 40rpx;
background: #FDECEC;
opacity: 0.5;
display: flex;
justify-content: center;
align-items: center;
margin-right: 20rpx;
.sex-text {
width: 28rpx;
height: 34rpx;
font-size: 28rpx;
font-weight: 500;
color: #36596A;
line-height: 34rpx;
}
}
.age {
@extend .address;
}
.dislevel {
@extend .address;
}
.contact {
@extend .address;
}
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 16rpx;
padding-bottom: 26rpx;
.distance {
align-items: center;
display: flex;
.distance-icon {
padding-left: 20rpx;
}
.distance-text {
height: 34rpx;
font-size: 24rpx;
font-weight: 500;
color: #A7AFBC;
line-height: 34rpx;
padding-left: 20rpx;
}
}
.to-there {
display: flex;
align-items: center;
margin-right: 20rpx;
.to-there-text {
height: 34rpx;
font-size: 24rpx;
font-weight: 500;
color: #A7AFBC;
line-height: 34rpx;
margin-right: 14rpx;
}
.to-there-icon {
margin-left: 3rpx;
}
}
}
}
}
.nearby-fab {
position: fixed;
right: 32rpx;
bottom: 120rpx;
width: 140rpx;
height: 140rpx;
background: #1479FF;
color: #FFFFFF;
border-radius: 70rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 6rpx 20rpx rgba(20, 121, 255, 0.35);
z-index: 9;
}
.nearby-fab-text {
font-size: 26rpx;
font-weight: 600;
}
</style>