pad-app/components/fjj-condition/fjj-condition.vue

606 lines
17 KiB
Vue
Raw Permalink Blame History

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>
<uni-drawer :visible="visibleDrawer" :hideNoAnimate="showBackButton" mode="right" @close="closeDrawer()">
<!-- #ifdef APP-PLUS -->
<view class="iconfont icon-guanbi" v-if="showBackButton" @tap="closeDrawer()"></view>
<!-- #endif -->
<scroll-view class="drawer-list" scroll-y :style="{'height': drawerHeight, 'padding-top': fixTop}">
<block v-for="(item, index) in menuList" :key="index">
<!-- isMutiple-->
<view v-if="item.type === 'custom' && item.detailList.length">
<view class="drawer-list-title flex justify-between">
<view>
{{item.title}}
</view>
<text v-if="item.detailList.length>showLenght"
@tap="showMore(index)">{{item.showMoreList ? '收起' : '更多'}}</text>
</view>
<view class="draer-list-con">
<template v-if="!item.showMoreList">
<text
:style="{background: textItem.isSelected ? color : '', color: textItem.isSelected ? '#ffffff' : ''}"
v-if="idx<showLenght" v-for="(textItem, idx) in item.detailList" :key="idx"
:class="textItem.isSelected ? 'on' : ''"
@tap="itemTap(idx,item.detailList,item.key, item.isMutiple)">
{{textItem.title}}
</text>
</template>
<template v-else>
<text
:style="{background: textItem.isSelected ? color : '', color: textItem.isSelected ? '#ffffff' : ''}"
v-for="(textItem, idx) in item.detailList" :key="idx"
:class="textItem.isSelected ? 'on' : ''"
@tap="itemTap(idx,item.detailList,item.key, item.isMutiple)">
{{textItem.title}}
</text>
</template>
</view>
</view>
<!-- 时间带时分秒范围选择 -->
<view v-if="item.type === 'rangetime'">
<view class="drawer-list-title flex justify-between">
<view>
{{item.title}}
</view>
</view>
<view class="dateContent" @click="onShowDatePicker('rangetime', item.key, item)">
<view>
<template v-if="result[item.key] && result[item.key].length > 0">
{{result[item.key][0]}}
</template>
</view>
<view>
<template v-if="result[item.key] && result[item.key].length > 0">
{{result[item.key][1]}}
</template>
</view>
</view>
</view>
<!-- 时间不带时分秒范围选择 -->
<view v-if="item.type === 'range'">
<view class="drawer-list-title flex justify-between">
<view>
{{item.title}}
</view>
</view>
<view class="dateContent" @click="onShowDatePicker('range', item.key, item)">
<view>
<template v-if="result[item.key] && result[item.key].length > 0">
{{result[item.key][0]}}-{{result[item.key][1]}}
</template>
</view>
</view>
</view>
<!-- 时间选择 -->
<view v-if="item.type === 'date'">
<view class="drawer-list-title flex justify-between">
<view>
{{item.title}}
</view>
</view>
<view class="dateContent" @click="onShowDatePicker('date', item.key, item)">
<view>
<template v-if="result[item.key]">
{{result[item.key]}}
</template>
</view>
</view>
</view>
<!-- 数值范围选择 -->
<view v-if="item.type === 'rangenumber'">
<view class="drawer-list-title flex justify-between">
<view>
{{item.title}}
</view>
</view>
<view class="dateContent rangenumber-content flex">
<view class="rangenumber-input">
<input class="m-input" type="number" clearable v-model="result[item.minName || (item.key + 'Min')]"
:placeholder="item.minPlaceholder || '最小值'"
@blur="numberInputBlur(item)"></input>
</view>
<text>-</text>
<view class="rangenumber-input">
<input class="m-input" type="number" clearable v-model="result[item.maxName || (item.key + 'Max')]"
:placeholder="item.maxPlaceholder || '最大值'"
@blur="numberInputBlur(item)"></input>
</view>
</view>
</view>
<!-- 单输入框 -->
<view v-if="item.type === 'singleinput'">
<view class="drawer-list-title flex justify-between">
<view>
{{item.title}}
</view>
</view>
<view class="dateContent">
<view>
<input class="m-input" clearable v-model="result[item.key]"
:placeholder="item.placeholder || '请输入关键字'" />
</view>
</view>
</view>
</block>
</scroll-view>
<view class="filter-content-footer flex justify-center">
<!-- #ifdef APP-PLUS-->
<view v-if="showBackButton" class="filter-content-footer-item" :style="{color: '#ccc', 'border': '1rpx solid #ccc'}"
@tap="closeDrawer()">
<text>返回</text>
</view>
<!-- #endif -->
<view class="filter-content-footer-item" :style="{color, 'border': `1rpx solid ${color}`}"
@tap="resetClick">
<text>重置</text>
</view>
<view class="filter-content-footer-item" :style="{'background': color}" @tap="sureClick">
<text>确认</text>
</view>
</view>
</uni-drawer>
<mx-date-picker :show="showPicker" :color="color" :type="dateType" :value="dateValue" :show-tips="true"
:show-seconds="true" @confirm="onSelected" @cancel="onSelected" />
</view>
</template>
<script>
/***
* 筛选组件,当前支持多选、单选
* item.type (custom 单选、多选、rangetime 时间范围带时分秒、range 时间范围不带时分秒、rangenumber 数字范围)
* item.isMutiple 是否支持多选
* 筛选后返回格式{"listName1":[value,value](多选),"listName2":"value"(单选),...}
* rangenumber形式-可能为["",1]或[1,""]表示只有一个最大值或最小值
***/
import uniDrawer from '@/components/uni-drawer/uni-drawer.vue';
import MxDatePicker from "@/components/mx-datepicker/mx-datepicker.vue";
export default {
props: {
list: {
required: true,
type: Array,
default () {
return [];
},
},
color: {
type: String,
default: '#4D7BFE',
},
defaultValue: { //若有默认值则触发sureClick
type: Object,
default () {
return {}
},
},
showBackButton: {
type: Boolean,
default: false,
}
},
watch: {
list: {
handler(val) {
this.menuList = JSON.parse(JSON.stringify(val));
this.resetResult();
this.defaultValueFun();
},
deep: true // 可以深度检测到 obj 对象的属性值的变化
}
},
components: {
uniDrawer,
MxDatePicker
},
beforeCreate() {
Object.isEmpty = (object, except = []) => {
if (!object) {
return false;
}
for (let key in object) {
if (except && except.includes(key)) {
continue;
}
if (object.hasOwnProperty(key)) {
return false;
}
}
return true;
};
Date.prototype.Format = function(fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1
.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[
k]) : (("00" + o[
k]).substr(("" + o[k]).length)));
return fmt;
};
String.prototype.replaceAll = function(oldValue, newValue) { return this.toString().replace(new RegExp(oldValue, 'gm'), newValue); }
},
created() {
this.menuList = JSON.parse(JSON.stringify(this.list));
this.resetResult();
uni.getSystemInfo({
success: (res) => {
let windowHeight = res.windowHeight;
// #ifdef H5
if (!(this.$IsWeixin || this.$IsAlipay || this.$IsCloudPay)) {
let thirdApp = getApp().globalData.options?.thirdApp;
if (thirdApp && thirdApp.hideNavBar) {
// 第三方App使用App原生导航栏
} else {
this.fixTop = (res.statusBarHeight || 0) + 'px';
}
}
windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body
.clientHeight || res.windowHeight;
// #endif
this.drawerHeight = (windowHeight - uni.upx2px(120)) + 'px';
// uni.showModal({
// content: `model: ${res.model}`,
// })
}
});
},
mounted() {
this.defaultValueFun();
},
computed: {
},
data() {
return {
menuList: [],
visibleDrawer: false,
menuKey: 1,
showLenght: 6,
drawerHeight: '500px',
selectDetailList: [],
result: {},
showPicker: false,
dateType: 'rangetime',
dateValue: '',
fixTop: '0px'
};
},
methods: {
defaultValueFun() {
//如果有默认值则赋值后调用sureClick通知父组件更新
if (!Object.isEmpty(this.defaultValue)) {
const value = this.defaultValue;
const list = JSON.parse(JSON.stringify(this.menuList));
for (let key in value) {
for (let i = 0; i < list.length; i++) {
if (list[i].key === key) {
if (list[i].type === 'custom') {
list[i].detailList.map((item, index) => {
if (Array.isArray(value[key]) && value[key].indexOf(item.value) > -1) {
item.isSelected = true;
} else if (value[key] == item.value) {
item.isSelected = true;
}
return item;
})
continue;
}
if (list[i].type === 'range' || list[i].type === 'rangetime' || list[i].type === 'rangenumber' && Array.isArray(value[key]) && value[key].length === 2) {
this.result[key] = value[key];
this.result[list[i].minName || (list[i].key + 'Min')] = value[key][0];
this.result[list[i].maxName || (list[i].key + 'Max')] = value[key][1];
continue;
}
if (list[i].type === 'date' || list[i].type === 'singleinput' && value[key]) {
this.result[key] = value[key];
continue;
}
}
}
}
if (this.defaultRefeshTimer) {
clearTimeout(this.defaultRefesh·Timer);
}
this.defaultRefeshTimer = setTimeout(() => {
console.log('筛选默认值触发')
this.menuList = list;
this.sureClick();
}, 200);
}
},
resetResult() {
this.result = this.commonResultObj();
},
commonResultObj() {
let obj = {};
this.menuList.map((item) => {
switch(item.type) {
case "custom":
item.isMutiple ? obj[item.key] = [] : obj[item.key] = '';
item.detailList.forEach(dListItem => {
dListItem.isSelected = dListItem.isSelected || false;
});
break;
case 'range':
case 'rangetime':
case 'rangenumber':
this.result[item.key] = [];
this.result[item.minName || (item.key + 'Min')] = '';
this.result[item.maxName || (item.key + 'Max')] = '';
break;
default:
obj[item.key] = '';
}
})
return obj;
},
//筛选项选中或取消
itemTap(index, list, key, isMutiple) {
if (isMutiple == true) {
list[index].isSelected = !list[index].isSelected;
if (list[index].isSelected) {
this.result[key].push(list[index].value);
} else {
list[index].isSelected = false;
var idx = this.result[key].indexOf(list[index].value);
this.result[key].splice(idx, 1);
}
} else {
this.result[key] = list[index].isSelected ? '' : list[index].value;
for (let i = 0; i < list.length; i++) {
if (index == i && !list[i].isSelected) {
list[i].isSelected = true
} else {
list[i].isSelected = false
}
}
}
// #ifdef H5 || APP-PLUS
this.$forceUpdate();
// #endif
},
sureClick() {
this.menuList.forEach(menu => {
let list = menu.detailList || [];
if (menu.type == 'custom' && list.length > 0) {
let selectedValueList = [];
list.forEach(item => {
if (item.isSelected) {
selectedValueList.push(item.value);
}
});
if (menu.isMutiple == true) {
this.result[menu.key] = selectedValueList;
} else {
this.result[menu.key] = selectedValueList[0] || '';
}
}
});
let str_result = {};
let hasChoose = false;
for (let key in this.result) {
if (typeof this.result[key] == 'object') {
str_result[key] = this.result[key].join(',');
if (!hasChoose) {
hasChoose = this.result[key].join(',') !== '' ? true : false;
}
} else {
str_result[key] = this.result[key];
if (!hasChoose) {
hasChoose = this.result[key] !== '' ? true : false;
}
}
}
this.$emit("result", {
'str_result': str_result,
'result': this.result,
'hasChoose': hasChoose,
'visibleDrawer': false
});
},
resetClick() {
this.minNumber = '';
this.maxNumber = '';
for (let key in this.result) {
if (typeof this.result[key] === 'object') {
this.result[key] = [];
} else {
this.result[key] = '';
}
}
for (let i = 0; i < this.menuList.length; i++) {
if (this.menuList[i].type === 'custom') {
for (let j = 0; j < this.menuList[i].detailList.length; j++) {
this.menuList[i].detailList[j].isSelected = false;
}
}
}
// #ifdef H5 || APP-PLUS
this.$forceUpdate();
// #endif
},
closeDrawer() {
this.visibleDrawer = false;
// #ifdef APP-PLUS
this.$emit("result", {
type: 1,
});
// #endif
},
showMore(index) {
this.menuList[index].showMoreList = !this.menuList[index].showMoreList;
++this.menuKey;
// #ifdef H5 || APP-NVUE
this.$forceUpdate();
// #endif
},
onShowDatePicker(type, key, item) { //显示
this.dateType = type;
this.dateValue = this.result[key] || '';
this.showPicker = true;
this.tempKey = key;
this.item = item;
},
onSelected(e, key) { //选择
this.showPicker = false;
if (e) {
this.result[this.tempKey] = e.value;
if (e.value && e.value.length && this.item && this.item.type !== 'date') {
let item = this.item;
this.result[item.minName || (item.key + 'Min')] = e.value[0].replaceAll('/', '-');
this.result[item.maxName || (item.key + 'Max')] = e.value[1].replaceAll('/', '-');
}
//选择的值
console.log('value => ' + e.value);
//原始的Date对象
console.log('date => ' + e.date);
}
},
numberInputBlur(item) {
let minNumber = this.result[item.minName || (item.key + 'Min')];
let maxNumber = this.result[item.maxName || (item.key + 'Max')];
if (minNumber != '' && maxNumber != '' && parseFloat(minNumber) > parseFloat(maxNumber)) {
let temp = minNumber;
this.result[item.minName || (item.key + 'Min')] = maxNumber;
this.result[item.maxName || (item.key + 'Max')] = temp;
}
this.result[item.key] = [];
this.result[item.key].push(minNumber && parseFloat(minNumber));
this.result[item.key].push(maxNumber && parseFloat(maxNumber));
}
}
}
</script>
<style lang="scss" scoped>
.flex {
display: flex;
}
.justify-between {
justify-content: space-between;
}
view,
scroll-view,
swiper,
button,
input,
textarea,
label,
navigator,
image {
box-sizing: border-box;
}
/* 筛选样式 */
.drawer-list {
padding: 0 20rpx;
font-size: 26rpx;
}
input {
font-size: 26rpx;
}
.drawer-list .drawer-list-title {
font-size: 34rpx;
font-weight: 400;
line-height: 48rpx;
margin: 38rpx 0 18rpx;
color: rgba(34, 34, 34, 1);
}
.drawer-list .drawer-list-title>text {
font-size: 26rpx;
color: #666666;
}
.drawer-list .draer-list-con>text {
background: rgba(93, 92, 254, 0.1);
border-radius: 28px;
color: #666666;
font-size: 28rpx;
padding: 10rpx 28rpx;
margin: 10rpx 10rpx 10rpx 0;
display: inline-block;
}
.filter-content-footer-item {
flex: 1;
height: 72rpx;
line-height: 72rpx;
text-align: center;
border-radius: 8rpx;
margin: 14rpx;
color: #FFFFFF;
}
.picker {
z-index: 99999 !important;
}
.dateContent {
&>view {
background: rgba(244, 244, 244, 1);
border-radius: 8rpx;
width: 100%;
height: 64rpx;
line-height: 64rpx;
margin-bottom: 12rpx;
padding: 0 12rpx;
}
}
.rangenumber-content {
&>text {
display: inline-block;
width: 10%;
text-align: center;
height: 64rpx;
line-height: 64rpx;
}
.rangenumber-input {
width: 45%;
display: inline-block;
padding: 0 12rpx;
}
}
.m-input {
height: 64rpx;
line-height: 64rpx;
}
::v-deep .picker {
z-index: 999;
}
.icon-guanbi {
position: fixed;
top: 40rpx;
right: 40rpx;
z-index: 1000;
}
</style>