master
xy 1 year ago
parent cc61162037
commit a7b7a72d4f

@ -0,0 +1,50 @@
<template>
<view>
<u-mask :show="value" @click="$emit('input', false)">
<view class="wrap" @tag.stop>
<image class="icon" src="~@/static/toShare.png" mode="aspectFit"></image>
<view class="text">
请点击右上角
<br>
将它发送给指定朋友或分享到朋友圈
</view>
</view>
</u-mask>
</view>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
};
},
onLoad() {
},
}
</script>
<style lang="scss">
.wrap {
display: flex;
flex-direction: column;
align-items: flex-end;
.icon {
width: 200rpx;
margin-right: 100rpx;
}
.text {
color: #fff;
font-weight: 600;
font-size: 34rpx;
text-align: right;
padding: 20rpx 20rpx 0 0;
}
}
</style>

@ -32,5 +32,8 @@ Vue.prototype.$qqmapsdk = new QQMapWX({
key: 'D5EBZ-C3BWP-HZIDG-VO6BE-P2MN5-ESFZO'
});
let mpShare = require('uview-ui/libs/mixin/mpShare.js');
Vue.mixin(mpShare)
app.$mount()

@ -315,12 +315,14 @@
</view>
</view>
<view class="bottom-bar" v-if="form.pay_status === 0">
<view class="bottom-bar">
<view class="price">
<text>实付</text>
<text>¥ {{ accompanyProduct.price }}</text>
</view>
<u-button
v-if="form.pay_status === 0"
style="margin-left: auto;"
shape="circle"
ripple
:custom-style="payBtnStyle"
@ -328,6 +330,7 @@
@click="pay"
>立即下单</u-button
>
<view v-if="orderId" class="more" @click="isShowMoreAction = true"></view>
</view>
<!-- 服务列表 -->
<u-popup
@ -427,6 +430,12 @@
mode="time"
@confirm="confirmTime"
></u-picker>
<!-- 更多操作-->
<u-action-sheet
safe-area-inset-bottom
:list="moreActionList"
v-model="isShowMoreAction"
@click="moreActionClick" />
<!-- 优惠不显示先 -->
<u-popup
@ -581,9 +590,12 @@ export default {
"font-size": "28rpx",
color: "#fff",
width: "288rpx",
"margin-right": "25rpx",
"margin-right": "25rpx"
},
//more action
isShowMoreAction: false,
// service
isShowService: false,
@ -862,6 +874,36 @@ export default {
});
}
},
//
moreActionClick(index) {
let name = this.moreActionList[index].text
let fn = () => {}
switch (this.moreActionList[index].tag) {
case 'cancel':
fn = () => this.$u.api.accompanyProductOrder({
id: this.orderId,
pay_status: -1
}).then(_ => {
this.getDetail()
})
break;
case 'chargeback':
break;
}
uni.showModal({
title: "操作",
content: `是否确认${name}`,
success: (status) => {
if (status.confirm) {
fn()
} else {
}
},
fail: () => {
},
})
}
},
computed: {
currentStep() {
@ -912,6 +954,21 @@ export default {
this.list_archive.find((i) => i.id === this.form.user_archive_id) || {}
);
},
moreActionList() {
if (this.form.pay_status === 0) {
return [{
text: '取消订单',
fontSize: 28,
tag: 'cancel'
}]
} else if (this.form.pay_status === 1) {
return [{
text: '退单',
fontSize: 28,
tag: 'chargeback'
}]
}
}
},
};
</script>
@ -1354,6 +1411,11 @@ export default {
font-size: 40rpx;
}
}
.more {
font-size: 26rpx;
color: #666;
padding-right: 20rpx;
}
}
.service-list {

@ -0,0 +1,280 @@
<template>
<view class="page">
<scroll-view
scroll-y
style="height: 100%; width: 100%"
@scrolltolower="reachBottom"
>
<view>
<view class="order" v-for="i in list" :key="i.id">
<view class="title">
<view class="title__name">
<u-tag size="mini" type="primary" mode="dark" shape="circleLeft" :text="i.type === 1 ? '陪诊' : '陪护'"></u-tag>
<text style="padding-left: 10rpx;">专享半天陪诊</text>
</view>
<view class="title__status">{{ statusFormat(i.pay_status) }}</view>
</view>
<view class="price">
<view class="price-icon">
<u-icon :name="i.cover ? i.cover.url : vuex_default_icon" size="30"></u-icon>
</view>
<view class="price-text">
<view class="price-text__num">{{ i.accompany_product ? i.accompany_product.price : 0 }}</view>
<view class="price-text__no"
>订单号 {{ i.no }}</view
>
</view>
</view>
<view class="info"
@click.stop.native="$u.route({
url: '/package_sub/pages/AddOrder/AddOrder',
params: {
order_id: i.id,
type: i.type,
site_id: i.hospital.site_id
}
})">
<view class="info__item">
<text>就诊城市</text>
<text>{{ i.city || ((i.hospital && i.hospital.site) ? i.hospital.site.name : "") || " " }}</text>
</view>
<view class="info__item">
<text>就诊医院</text>
<text>{{ i.hospital ? i.hospital.name : '' }}</text>
</view>
<view class="info__item">
<text>就诊人</text>
<text>{{ i.user_archive ? i.user_archive.name : i.user_archive_id }}</text>
</view>
<view class="info__item">
<text>就诊时间</text>
<text>{{ i.time ? $moment(i.time).format('YYYY年MM月DD日 HH:mm') : '' }}</text>
</view>
</view>
<view class="bottom">
<view class="time">
<text>下单时间 </text>
<text>{{ i.created_at ? $moment(i.created_at).format('YYYY年MM月DD日 HH:mm') : '' }}</text>
</view>
<u-button ripple
shape="circle"
:custom-style="payBtnStyle"
:throttle-time="2000"
@click="$u.route({
url: '/package_sub/pages/AddOrder/AddOrder',
params: {
order_id: i.id,
type: i.type,
site_id: i.hospital.site_id
}
})"
>{{ i.pay_status === 0 ? '立即支付' : '查看订单' }}</u-button
>
</view>
</view>
<u-loadmore
:status="loadStatus"
bgColor="#f2f2f2"
></u-loadmore>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
payBtnStyle: {
"background-image":
"linear-gradient(-90deg, #e26165 0%, #c10d12 94%, #c10d12 100%)",
"font-weight": "500",
"font-size": "28rpx",
color: "#fff",
width: "185rpx",
height: "60rpx",
"line-height": "60rpx",
},
loadStatus: 'loadmore',
list: [],
total: 0,
select: {
page: 1,
pay_status: "",
page_size: 20,
},
};
},
computed: {
statusFormat() {
return function (status) {
return this.vuex_order_status.find(i => i.value === status)?.name
}
}
},
methods: {
reachBottom() {
this.getOrder()
},
query2select(option) {
for (let key in option) {
this.select[key] = option[key]
}
},
async getOrder(isRefresh=false) {
if (isRefresh) {
this.select.page = 1;
this.loadStatus = 'loadmore'
}
if (this.loadStatus === 'nomore') return
try {
this.loadStatus = 'loading'
const res = await this.$u.api.accompanyOrders(this.select);
console.log(res);
this.total = res.total;
if (isRefresh) {
this.list.length = 0;
}
this.list.push(...res.data)
if (this.list.length >= res.total) {
this.loadStatus = 'nomore'
} else {
this.loadStatus = 'loadmore'
}
} catch (err) {
console.error(err);
this.loadStatus = 'loadmore'
}
},
},
onLoad(option) {
this.query2select(option)
this.getOrder(true)
},
}
</script>
<style lang="scss">
.page {
padding-top: 24rpx;
padding-bottom: calc(20rpx);
padding-bottom: calc(
constant(safe-area-inset-bottom) + 20rpx
);
padding-bottom: calc(
env(safe-area-inset-bottom) + 20rpx
);
}
.order {
border-radius: 10rpx;
filter: drop-shadow(0 0 10rpx rgba(211, 211, 214, 0.3));
background-color: #ffffff;
margin: 0 25rpx 24rpx;
.title {
display: flex;
align-items: center;
padding: 37rpx 39rpx 32rpx 45rpx;
position: relative;
&__name {
font-size: 24rpx;
color: #333333;
font-weight: bold;
}
&__status {
font-size: 24rpx;
color: #c20d12;
font-weight: 500;
margin-left: auto;
}
&::after {
content: "";
height: 2rpx;
background: #999999;
opacity: 0.302;
position: absolute;
bottom: 0;
left: 39rpx;
right: 39rpx;
}
}
.price {
display: flex;
align-items: center;
padding: 28rpx 0 0 44rpx;
&-icon {
display: flex;
justify-content: center;
align-items: center;
width: 90rpx;
height: 84rpx;
border-radius: 10rpx;
background-color: #f3e7d8;
}
&-text {
padding-left: 28rpx;
&__num {
font-size: 24rpx;
color: #000000;
font-weight: bold;
}
&__no {
font-size: 24rpx;
color: #999999;
font-weight: 500;
padding-top: 14rpx;
}
}
}
.info {
display: flex;
flex-wrap: wrap;
padding: 35rpx 45rpx 0;
&__item {
flex-basis: 50%;
color: #333;
font-size: 24rpx;
font-weight: 500;
display: flex;
margin-bottom: 32rpx;
& > text {
display: block;
}
& > text:nth-child(1) {
color: #999;
padding-right: 20rpx;
flex: 0;
word-break: keep-all;
}
& > text:nth-child(2) {
}
}
}
.bottom {
padding: 6rpx 28rpx 35rpx 43rpx;
display: flex;
align-items: center;
justify-content: space-between;
.time {
font-size: 24rpx;
color: #999999;
font-weight: 500;
}
}
}
</style>

@ -5,7 +5,7 @@
<view class="position" @click="isShowSite = true">
<u-icon name="map-fill"></u-icon>
<!-- <text>{{ vuex_location.city.replace(/(市|区|县)/,'') }}</text> -->
<text>{{select.site_name}}</text>
<text>{{ vuex_site.name || ' ' }}</text>
<u-icon name="arrow-down" size="22"></u-icon>
</view>
</view>
@ -73,8 +73,6 @@
page: 1,
page_size: 5,
type: '',
site_id: '',
site_name: '全部站点'
},
list: [],
loadStatus: 'loadmore',
@ -104,7 +102,8 @@
},
async getList() {
const res = await this.$u.api.accompanyProduct({
...this.select
...this.select,
site_id: this.vuex_site?.id
})
this.last_page = res.last_page
this.loadStatus = this.select.page >= this.last_page ?'nomore':'loadmore'
@ -121,8 +120,7 @@
this.getList()
},
confirmSite(e) {
this.select.site_name = e[0].label
this.select.site_id = e[0].value
this.$u.vuex("vuex_site", e[0])
this.list = []
this.select.page = 1
this.getList()

@ -59,7 +59,7 @@
}
},
{
"path": "ServiceObject/ServiceObject",
"path": "pages/ServiceObject/ServiceObject",
"style": {
"navigationBarTitleText": "服务对象"
}
@ -70,6 +70,13 @@
"navigationBarTitleText": "我的服务人员",
"enablePullDownRefresh": true
}
},
{
"path": "pages/OrderList/OrderList",
"style": {
"navigationBarTitleText": "订单",
"enablePullDownRefresh": true
}
}
]
}

@ -10,10 +10,11 @@
<view class="top" :style="{ 'padding-right': menuButtonRight + 'px' }">
<view
class="position"
@click="$u.route({ url: '/pages/CitySelect/CitySelect' })"
@click="isShowSite = true"
>
<u-icon name="map-fill"></u-icon>
<view>{{ vuex_location.city.replace(/(市|区|县)/, "") }}</view>
<view>{{ vuex_site.name }}</view>
<!-- <view>{{ vuex_location.city.replace(/(市|区|县)/, "") }}</view>-->
<u-icon name="arrow-down" size="22"></u-icon>
</view>
<view class="icon">
@ -45,9 +46,10 @@
'padding-right': menuButtonRight + 'px',
}"
>
<view class="search-sticky__position" @click="$u.route({ url: '/pages/CitySelect/CitySelect' })">
<view class="search-sticky__position" @click="isShowSite = true">
<u-icon name="map-fill"></u-icon>
<view>{{ vuex_location.city.replace(/(市|区|县)/, "") }}</view>
<view>{{ vuex_site.name }}</view>
<!-- <view>{{ vuex_location.city.replace(/(市|区|县)/, "") }}</view>-->
<u-icon name="arrow-down" size="22"></u-icon>
</view>
@ -192,9 +194,9 @@
<scroll-view class="scroll-content" scroll-x="true">
<image
class="images"
v-for="i in 5"
:key="i"
src="https://sstt.115.langye.net/storage/files/172760356266f9236a22e58.png"
v-for="i in photos"
:key="i.id"
:src="i.image ? i.image.url : ''"
mode="aspectFit"
></image>
</scroll-view>
@ -208,6 +210,13 @@
></image>
</view>
<!-- 选择站点 -->
<u-select v-model="isShowSite"
value-name="id"
@confirm="confirmSite"
label-name="name"
:list="list_site"></u-select>
<u-top-tips :navbar-height="navbarHeight" ref="uTips"></u-top-tips>
<tabbar />
@ -226,6 +235,12 @@ export default {
},
data() {
return {
isShowSite: false,
list_site: [{
id: '',
name: '全部站点'
}],
isShowSticky: false,
scrollTop: 308,
statusBarHeight: 40,
@ -266,23 +281,27 @@ export default {
hospitals: [],
banners: [],
photos: [],
};
},
mounted() {
this.getElScrollTop();
if (this.$store.state.vuex_location.status !== 2) {
this.$store.dispatch("getLocation");
}
// if (this.$store.state.vuex_location.status !== 2) {
// this.$store.dispatch("getLocation");
// }
},
created() {
onLoad() {
this.menuButtonRight =
uni.getSystemInfoSync().screenWidth -
uni.getMenuButtonBoundingClientRect().left +
10;
this.statusBarHeight = uni.getMenuButtonBoundingClientRect().top;
this.getHospital();
this.getBanner();
this.getSiteList().then(_ => {
this.getHospital();
this.getBanner();
this.getPhotos();
})
},
onPageScroll(e) {
this.isShowSticky = e.scrollTop > this.scrollTop;
@ -306,11 +325,26 @@ export default {
},
searchInput(e) {},
async getSiteList() {
const res = await this.$u.api.otherSite()
this.list_site.push(...res)
let defaultValue = res.find(i => i.name === '常州')
if (defaultValue && !this.vuex_site.id) {
this.$u.vuex('vuex_site', defaultValue)
}
},
confirmSite(e) {
this.$u.vuex('vuex_site', e[0])
this.getHospital()
this.getBanner()
this.getPhotos()
},
async getHospital() {
try {
const res = await this.$u.api.hospitalList({
page: 1,
page_size: 5,
site_id: this.vuex_site.id ? this.vuex_site.id : '',
"show_relation[0]": "site",
});
this.hospitals = res.data;
@ -320,13 +354,23 @@ export default {
try {
const res = await this.$u.api.banner({
position: 1,
site_id: this.vuex_site.id ? this.vuex_site.id : '',
});
this.banners = res.map((i) => ({
...i,
url: i.image?.url,
url: i.image?.url ?? '',
}));
} catch (err) {}
},
async getPhotos() {
try {
const res = await this.$u.api.banner({
position: 2,
site_id: this.vuex_site.id ? this.vuex_site.id : '',
});
this.photos = res
} catch (err) {}
},
},
};
</script>

@ -12,7 +12,13 @@
</view>
<view class="panel panel1">
<view class="tab">
<view class="tab"
@click="$u.route({
url: '/package_sub/pages/OrderList/OrderList',
params: {
type: 1
}
})">
<image class="tab__icon" mode="aspectFit" src="~@/static/index/jiuyifuwu.png"></image>
<view>陪诊订单</view>
</view>
@ -20,7 +26,13 @@
<image class="tab__icon" mode="aspectFit" src="~@/static/index/jiuyifuwu.png"></image>
<view>商城订单</view>
</view>
<view class="tab">
<view class="tab"
@click="$u.route({
url: '/package_sub/pages/OrderList/OrderList',
params: {
type: 2
}
})">
<image class="tab__icon" mode="aspectFit" src="~@/static/index/jiuyifuwu.png"></image>
<view>居家照护订单</view>
</view>
@ -28,13 +40,18 @@
<image class="tab__icon" mode="aspectFit" src="~@/static/index/jiuyifuwu.png"></image>
<view>常用联系人</view>
</view>
<view class="tab">
<view class="tab"
@click="$u.route({
url: '/package_sub/pages/OrderList/OrderList',
params: {
}
})">
<image class="tab__icon" mode="aspectFit" src="~@/static/index/jiuyifuwu.png"></image>
<view>售后订单</view>
</view>
</view>
<view class="panel panel2">
<view class="row" @click="share">
<view class="row" @click="isShowShare = true">
<u-icon class="row__icon" name="share"></u-icon>
<view>我要分享</view>
</view>
@ -52,18 +69,22 @@
</view>
</view>
<tabbar />
<share v-model="isShowShare" />
</view>
</template>
<script>
import Tabbar from "@/component/Tabbar/Tabbar.vue";
import Share from "@/component/Share/Share.vue";
export default {
components: {
Tabbar
Tabbar,
Share
},
data() {
return {
isShowShare: false
};
},
methods: {

@ -54,7 +54,15 @@
</view>
</view>
<view class="info">
<view class="info"
@click.stop.native="$u.route({
url: '/package_sub/pages/AddOrder/AddOrder',
params: {
order_id: i.id,
type: i.type,
site_id: i.hospital.site_id
}
})">
<view class="info__item">
<text>就诊城市</text>
<text>{{ i.city || ((i.hospital && i.hospital.site) ? i.hospital.site.name : "") || " " }}</text>
@ -184,7 +192,7 @@ export default {
computed: {
statusFormat() {
return function (status) {
return this.tabs.find(i => i.value === status)?.name
return this.vuex_order_status.find(i => i.value === status)?.name
}
}
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

@ -38,13 +38,42 @@ const store = new Vuex.Store({
vuex_token: '',
vuex_user: {},
vuex_site: {
name: '',
id: ''
},
vuex_location: {
latitude: '',
longitude: '',
city: '',
cityCode: '',
status: 0, // 0失败 1成功 2手动选择
}
},
vuex_order_status: [
{
name: "全部",
value: "",
},
{
name: "待支付",
value: 0,
},
{
name: "已支付",
value: 1,
},
{
name: "服务中",
value: 2,
},
{
name: "已完成",
value: 3,
},
// {
// name: '已取消'
// }
]
},
mutations: {
$uStore(state, payload) {

@ -1,351 +1,351 @@
<template>
<view class="u-select">
<!-- <view class="u-select__action" :class="{
'u-select--border': border
}" @tap.stop="selectHandler">
<view class="u-select__action__icon" :class="{
'u-select__action__icon--reverse': value == true
}">
<u-icon name="arrow-down-fill" size="26" color="#c0c4cc"></u-icon>
</view>
</view> -->
<u-popup :maskCloseAble="maskCloseAble" mode="bottom" :popup="false" v-model="value" length="auto" :safeAreaInsetBottom="safeAreaInsetBottom" @close="close" :z-index="uZIndex">
<view class="u-select">
<view class="u-select__header" @touchmove.stop.prevent="">
<view
class="u-select__header__cancel u-select__header__btn"
:style="{ color: cancelColor }"
hover-class="u-hover-class"
:hover-stay-time="150"
@tap="getResult('cancel')"
>
{{cancelText}}
</view>
<view class="u-select__header__title">
{{title}}
</view>
<view
class="u-select__header__confirm u-select__header__btn"
:style="{ color: moving ? cancelColor : confirmColor }"
hover-class="u-hover-class"
:hover-stay-time="150"
@touchmove.stop=""
@tap.stop="getResult('confirm')"
>
{{confirmText}}
</view>
</view>
<view class="u-select__body">
<picker-view @change="columnChange" class="u-select__body__picker-view" :value="defaultSelector" @pickstart="pickstart" @pickend="pickend">
<picker-view-column v-for="(item, index) in columnData" :key="index">
<view class="u-select__body__picker-view__item" v-for="(item1, index1) in item" :key="index1">
<view class="u-line-1">{{ item1[labelName] }}</view>
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</u-popup>
</view>
<view class="u-select">
<!-- <view class="u-select__action" :class="{
'u-select--border': border
}" @tap.stop="selectHandler">
<view class="u-select__action__icon" :class="{
'u-select__action__icon--reverse': value == true
}">
<u-icon name="arrow-down-fill" size="26" color="#c0c4cc"></u-icon>
</view>
</view> -->
<u-popup :maskCloseAble="maskCloseAble" mode="bottom" :popup="false" v-model="value" length="auto" :safeAreaInsetBottom="safeAreaInsetBottom" @close="close" :z-index="uZIndex">
<view class="u-select">
<view class="u-select__header" @touchmove.stop.prevent="">
<view
class="u-select__header__cancel u-select__header__btn"
:style="{ color: cancelColor }"
hover-class="u-hover-class"
:hover-stay-time="150"
@tap="getResult('cancel')"
>
{{cancelText}}
</view>
<view class="u-select__header__title">
{{title}}
</view>
<view
class="u-select__header__confirm u-select__header__btn"
:style="{ color: moving ? cancelColor : confirmColor }"
hover-class="u-hover-class"
:hover-stay-time="150"
@touchmove.stop=""
@tap.stop="getResult('confirm')"
>
{{confirmText}}
</view>
</view>
<view class="u-select__body">
<picker-view @change="columnChange" class="u-select__body__picker-view" :value="defaultSelector" @pickstart="pickstart" @pickend="pickend">
<picker-view-column v-for="(item, index) in columnData" :key="index">
<view class="u-select__body__picker-view__item" v-for="(item1, index1) in item" :key="index1">
<view class="u-line-1">{{ item1[labelName] }}</view>
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
/**
* select 列选择器
* @description 此选择器用于单列多列多列联动的选择场景(从1.3.0版本起不建议使用Picker组件的单列和多列模式Select组件是专门为列选择而构造的组件更简单易用)
* @tutorial http://uviewui.com/components/select.html
* @property {String} mode 模式选择"single-column"-单列模式"mutil-column"-多列模式"mutil-column-auto"-多列联动模式
* @property {Array} list 列数据数组形式见官网说明
* @property {Boolean} v-model 布尔值变量用于控制选择器的弹出与收起
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
* @property {String} cancel-color 取消按钮的颜色默认#606266
* @property {String} confirm-color 确认按钮的颜色(默认#2979ff)
* @property {String} confirm-text 确认按钮的文字
* @property {String} cancel-text 取消按钮的文字
* @property {String} default-value 提供的默认选中的下标见官网说明
* @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)
* @property {String Number} z-index 弹出时的z-index值(默认10075)
* @property {String} value-name 自定义list数据的value属性名 1.3.6
* @property {String} label-name 自定义list数据的label属性名 1.3.6
* @property {String} child-name 自定义list数据的children属性名只对多列联动模式有效 1.3.7
* @event {Function} confirm 点击确定按钮返回当前选择的值
* @example <u-select v-model="show" :list="list"></u-select>
*/
/**
* select 列选择器
* @description 此选择器用于单列多列多列联动的选择场景(从1.3.0版本起不建议使用Picker组件的单列和多列模式Select组件是专门为列选择而构造的组件更简单易用)
* @tutorial http://uviewui.com/components/select.html
* @property {String} mode 模式选择"single-column"-单列模式"mutil-column"-多列模式"mutil-column-auto"-多列联动模式
* @property {Array} list 列数据数组形式见官网说明
* @property {Boolean} v-model 布尔值变量用于控制选择器的弹出与收起
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
* @property {String} cancel-color 取消按钮的颜色默认#606266
* @property {String} confirm-color 确认按钮的颜色(默认#2979ff)
* @property {String} confirm-text 确认按钮的文字
* @property {String} cancel-text 取消按钮的文字
* @property {String} default-value 提供的默认选中的下标见官网说明
* @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)
* @property {String Number} z-index 弹出时的z-index值(默认10075)
* @property {String} value-name 自定义list数据的value属性名 1.3.6
* @property {String} label-name 自定义list数据的label属性名 1.3.6
* @property {String} child-name 自定义list数据的children属性名只对多列联动模式有效 1.3.7
* @event {Function} confirm 点击确定按钮返回当前选择的值
* @example <u-select v-model="show" :list="list"></u-select>
*/
export default {
props: {
//
list: {
type: Array,
default() {
return [];
}
},
//
border: {
type: Boolean,
default: true
},
//
value: {
type: Boolean,
default: false
},
// ""
cancelColor: {
type: String,
default: '#606266'
},
// ""
confirmColor: {
type: String,
default: '#2979ff'
},
// z-index
zIndex: {
type: [String, Number],
default: 0
},
safeAreaInsetBottom: {
type: Boolean,
default: false
},
// Picker
maskCloseAble: {
type: Boolean,
default: true
},
//
defaultValue: {
type: Array,
default() {
return [0];
}
},
// single-column-mutil-column-mutil-column-auto-
mode: {
type: String,
default: 'single-column'
},
// value
valueName: {
type: String,
default: 'value'
},
// label
labelName: {
type: String,
default: 'label'
},
// children
childName: {
type: String,
default: 'children'
},
//
title: {
type: String,
default: ''
},
//
cancelText: {
type: String,
default: '取消'
},
//
confirmText: {
type: String,
default: '确认'
}
},
data() {
return {
//
defaultSelector: [0],
// picker-view
columnData: [],
//
selectValue: [],
// index
lastSelectIndex: [],
//
columnNum: 0,
//
moving: false
};
},
watch: {
// select
value: {
immediate: true,
handler(val) {
if(val) setTimeout(() => this.init(), 10);
}
},
},
computed: {
uZIndex() {
// z-index使
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
},
},
methods: {
//
pickstart() {
// #ifdef MP-WEIXIN
this.moving = true;
// #endif
},
//
pickend() {
// #ifdef MP-WEIXIN
this.moving = false;
// #endif
},
init() {
this.setColumnNum();
this.setDefaultSelector();
this.setColumnData();
this.setSelectValue();
},
//
setDefaultSelector() {
// columnNum0
this.defaultSelector = this.defaultValue.length == this.columnNum ? this.defaultValue : Array(this.columnNum).fill(0);
this.lastSelectIndex = this.$u.deepClone(this.defaultSelector);
},
//
setColumnNum() {
// 1
if(this.mode == 'single-column') this.columnNum = 1;
// this.list
else if(this.mode == 'mutil-column') this.columnNum = this.list.length;
// this.list
else if(this.mode == 'mutil-column-auto') {
let num = 1;
let column = this.list;
// children
while(column[0][this.childName]) {
column = column[0] ? column[0][this.childName] : {};
num ++;
}
this.columnNum = num;
}
},
// picker
setColumnData() {
let data = [];
this.selectValue = [];
if(this.mode == 'mutil-column-auto') {
//
let column = this.list[this.defaultSelector.length ? this.defaultSelector[0] : 0];
//
for (let i = 0; i < this.columnNum; i++) {
// list
if (i == 0) {
data[i] = this.list;
column = column[this.childName];
} else {
//
data[i] = column;
column = column[this.defaultSelector[i]][this.childName];
}
}
} else if(this.mode == 'single-column') {
data[0] = this.list;
} else {
data = this.list;
}
this.columnData = data;
},
// defaultValue
setSelectValue() {
let tmp = null;
for(let i = 0; i < this.columnNum; i++) {
tmp = this.columnData[i][this.defaultSelector[i]];
let data = {
value: tmp ? tmp[this.valueName] : null,
label: tmp ? tmp[this.labelName] : null
};
//
if(tmp && tmp.extra) data.extra = tmp.extra;
this.selectValue.push(data)
}
},
//
columnChange(e) {
let index = null;
let columnIndex = e.detail.value;
// push
this.selectValue = [];
if(this.mode == 'mutil-column-auto') {
//
this.lastSelectIndex.map((val, idx) => {
if (val != columnIndex[idx]) index = idx;
});
this.defaultSelector = columnIndex;
for (let i = index + 1; i < this.columnNum; i++) {
// children
//
this.columnData[i] = this.columnData[i - 1][i - 1 == index ? columnIndex[index] : 0][this.childName];
//
this.defaultSelector[i] = 0;
}
// this.columnDatacolumnChange
// undefined
columnIndex.map((item, index) => {
let data = this.columnData[index][columnIndex[index]];
let tmp = {
value: data ? data[this.valueName] : null,
label: data ? data[this.labelName] : null,
};
//
if(data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
props: {
//
list: {
type: Array,
default() {
return [];
}
},
//
border: {
type: Boolean,
default: true
},
//
value: {
type: Boolean,
default: false
},
// ""
cancelColor: {
type: String,
default: '#606266'
},
// ""
confirmColor: {
type: String,
default: '#2979ff'
},
// z-index
zIndex: {
type: [String, Number],
default: 0
},
safeAreaInsetBottom: {
type: Boolean,
default: false
},
// Picker
maskCloseAble: {
type: Boolean,
default: true
},
//
defaultValue: {
type: Array,
default() {
return [0];
}
},
// single-column-mutil-column-mutil-column-auto-
mode: {
type: String,
default: 'single-column'
},
// value
valueName: {
type: String,
default: 'value'
},
// label
labelName: {
type: String,
default: 'label'
},
// children
childName: {
type: String,
default: 'children'
},
//
title: {
type: String,
default: ''
},
//
cancelText: {
type: String,
default: '取消'
},
//
confirmText: {
type: String,
default: '确认'
}
},
data() {
return {
//
defaultSelector: [0],
// picker-view
columnData: [],
//
selectValue: [],
// index
lastSelectIndex: [],
//
columnNum: 0,
//
moving: false
};
},
watch: {
// select
value: {
immediate: true,
handler(val) {
if(val) setTimeout(() => this.init(), 10);
}
},
},
computed: {
uZIndex() {
// z-index使
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
},
},
methods: {
//
pickstart() {
// #ifdef MP-WEIXIN
this.moving = true;
// #endif
},
//
pickend() {
// #ifdef MP-WEIXIN
this.moving = false;
// #endif
},
init() {
this.setColumnNum();
this.setDefaultSelector();
this.setColumnData();
this.setSelectValue();
},
//
setDefaultSelector() {
// columnNum0
this.defaultSelector = this.defaultValue.length == this.columnNum ? this.defaultValue : Array(this.columnNum).fill(0);
this.lastSelectIndex = this.$u.deepClone(this.defaultSelector);
},
//
setColumnNum() {
// 1
if(this.mode == 'single-column') this.columnNum = 1;
// this.list
else if(this.mode == 'mutil-column') this.columnNum = this.list.length;
// this.list
else if(this.mode == 'mutil-column-auto') {
let num = 1;
let column = this.list;
// children
while(column[0][this.childName]) {
column = column[0] ? column[0][this.childName] : {};
num ++;
}
this.columnNum = num;
}
},
// picker
setColumnData() {
let data = [];
this.selectValue = [];
if(this.mode == 'mutil-column-auto') {
//
let column = this.list[this.defaultSelector.length ? this.defaultSelector[0] : 0];
//
for (let i = 0; i < this.columnNum; i++) {
// list
if (i == 0) {
data[i] = this.list;
column = column[this.childName];
} else {
//
data[i] = column;
column = column[this.defaultSelector[i]][this.childName];
}
}
} else if(this.mode == 'single-column') {
data[0] = this.list;
} else {
data = this.list;
}
this.columnData = data;
},
// defaultValue
setSelectValue() {
let tmp = null;
for(let i = 0; i < this.columnNum; i++) {
tmp = this.columnData[i][this.defaultSelector[i]];
let data = {
value: tmp ? tmp[this.valueName] : null,
label: tmp ? tmp[this.labelName] : null
};
//
if(tmp && tmp.extra) data.extra = tmp.extra;
this.selectValue.push(data)
}
},
//
columnChange(e) {
let index = null;
let columnIndex = e.detail.value;
// push
this.selectValue = [];
if(this.mode == 'mutil-column-auto') {
//
this.lastSelectIndex.map((val, idx) => {
if (val != columnIndex[idx]) index = idx;
});
this.defaultSelector = columnIndex;
for (let i = index + 1; i < this.columnNum; i++) {
// children
//
this.columnData[i] = this.columnData[i - 1][i - 1 == index ? columnIndex[index] : 0][this.childName];
//
this.defaultSelector[i] = 0;
}
// this.columnDatacolumnChange
// undefined
columnIndex.map((item, index) => {
let data = this.columnData[index][columnIndex[index]];
let tmp = {
[this.valueName ? this.valueName : 'value']: data ? data[this.valueName] : null,
[this.labelName ? this.labelName : 'label']: data ? data[this.labelName] : null,
};
//
if(data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
})
//
this.lastSelectIndex = columnIndex;
} else if(this.mode == 'single-column') {
let data = this.columnData[0][columnIndex[0]];
//
let tmp = {
value: data ? data[this.valueName] : null,
label: data ? data[this.labelName] : null,
};
//
if(data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
} else if(this.mode == 'mutil-column') {
//
columnIndex.map((item, index) => {
let data = this.columnData[index][columnIndex[index]];
//
let tmp = {
value: data ? data[this.valueName] : null,
label: data ? data[this.labelName] : null,
};
//
if(data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
})
}
},
close() {
this.$emit('input', false);
},
//
getResult(event = null) {
// #ifdef MP-WEIXIN
if (this.moving) return;
// #endif
if (event) this.$emit(event, this.selectValue);
this.close();
},
selectHandler() {
this.$emit('click');
}
}
})
//
this.lastSelectIndex = columnIndex;
} else if(this.mode == 'single-column') {
let data = this.columnData[0][columnIndex[0]];
//
let tmp = {
[this.valueName ? this.valueName : 'value']: data ? data[this.valueName] : null,
[this.labelName ? this.labelName : 'label']: data ? data[this.labelName] : null,
};
//
if(data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
} else if(this.mode == 'mutil-column') {
//
columnIndex.map((item, index) => {
let data = this.columnData[index][columnIndex[index]];
//
let tmp = {
[this.valueName ? this.valueName : 'value']: data ? data[this.valueName] : null,
[this.labelName ? this.labelName : 'label']: data ? data[this.labelName] : null,
};
//
if(data && data.extra !== undefined) tmp.extra = data.extra;
this.selectValue.push(tmp);
})
}
},
close() {
this.$emit('input', false);
},
//
getResult(event = null) {
// #ifdef MP-WEIXIN
if (this.moving) return;
// #endif
if (event) this.$emit(event, this.selectValue);
this.close();
},
selectHandler() {
this.$emit('click');
}
}
};
</script>
@ -354,64 +354,64 @@ export default {
.u-select {
&__action {
position: relative;
line-height: $u-form-item-height;
height: $u-form-item-height;
&__action {
position: relative;
line-height: $u-form-item-height;
height: $u-form-item-height;
&__icon {
position: absolute;
right: 20rpx;
top: 50%;
transition: transform .4s;
transform: translateY(-50%);
z-index: 1;
&__icon {
position: absolute;
right: 20rpx;
top: 50%;
transition: transform .4s;
transform: translateY(-50%);
z-index: 1;
&--reverse {
transform: rotate(-180deg) translateY(50%);
}
}
}
&--reverse {
transform: rotate(-180deg) translateY(50%);
}
}
}
&__hader {
&__title {
color: $u-content-color;
}
}
&__hader {
&__title {
color: $u-content-color;
}
}
&--border {
border-radius: 6rpx;
border-radius: 4px;
border: 1px solid $u-form-item-border-color;
}
&--border {
border-radius: 6rpx;
border-radius: 4px;
border: 1px solid $u-form-item-border-color;
}
&__header {
@include vue-flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
padding: 0 40rpx;
}
&__header {
@include vue-flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
padding: 0 40rpx;
}
&__body {
width: 100%;
height: 500rpx;
overflow: hidden;
background-color: #fff;
&__body {
width: 100%;
height: 500rpx;
overflow: hidden;
background-color: #fff;
&__picker-view {
height: 100%;
box-sizing: border-box;
&__picker-view {
height: 100%;
box-sizing: border-box;
&__item {
@include vue-flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: $u-main-color;
padding: 0 8rpx;
}
}
}
&__item {
@include vue-flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: $u-main-color;
padding: 0 8rpx;
}
}
}
}
</style>

Loading…
Cancel
Save