From 3af91858728bc78cfe3e735e627f5a87d73fa26c Mon Sep 17 00:00:00 2001
From: zhang <zc857179121@qq.com>
Date: 星期三, 08 十月 2025 11:12:22 +0800
Subject: [PATCH] 12
---
uni_modules/uni-table/components/uni-th/filter-dropdown.vue | 503 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 503 insertions(+), 0 deletions(-)
diff --git a/uni_modules/uni-table/components/uni-th/filter-dropdown.vue b/uni_modules/uni-table/components/uni-th/filter-dropdown.vue
new file mode 100644
index 0000000..fe8cd96
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-th/filter-dropdown.vue
@@ -0,0 +1,503 @@
+<template>
+ <view class="uni-filter-dropdown">
+ <view class="dropdown-btn" @click="onDropdown">
+ <view class="icon-select" :class="{active: canReset}" v-if="isSelect || isRange"></view>
+ <view class="icon-search" :class="{active: canReset}" v-if="isSearch">
+ <view class="icon-search-0"></view>
+ <view class="icon-search-1"></view>
+ </view>
+ <view class="icon-calendar" :class="{active: canReset}" v-if="isDate">
+ <view class="icon-calendar-0"></view>
+ <view class="icon-calendar-1"></view>
+ </view>
+ </view>
+ <view class="uni-dropdown-cover" v-if="isOpened" @click="handleClose"></view>
+ <view class="dropdown-popup dropdown-popup-right" v-if="isOpened" @click.stop>
+ <!-- select-->
+ <view v-if="isSelect" class="list">
+ <label class="flex-r a-i-c list-item" v-for="(item,index) in dataList" :key="index"
+ @click="onItemClick($event, index)">
+ <check-box class="check" :checked="item.checked" />
+ <view class="checklist-content">
+ <text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+ </view>
+ </label>
+ </view>
+ <view v-if="isSelect" class="flex-r opera-area">
+ <view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSelectReset">
+ {{resource.reset}}</view>
+ <view class="flex-f btn btn-submit" @click="handleSelectSubmit">{{resource.submit}}</view>
+ </view>
+ <!-- search -->
+ <view v-if="isSearch" class="search-area">
+ <input class="search-input" v-model="filterValue" />
+ </view>
+ <view v-if="isSearch" class="flex-r opera-area">
+ <view class="flex-f btn btn-submit" @click="handleSearchSubmit">{{resource.search}}</view>
+ <view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSearchReset">
+ {{resource.reset}}</view>
+ </view>
+ <!-- range -->
+ <view v-if="isRange">
+ <view class="input-label">{{resource.gt}}</view>
+ <input class="input" v-model="gtValue" />
+ <view class="input-label">{{resource.lt}}</view>
+ <input class="input" v-model="ltValue" />
+ </view>
+ <view v-if="isRange" class="flex-r opera-area">
+ <view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleRangeReset">
+ {{resource.reset}}</view>
+ <view class="flex-f btn btn-submit" @click="handleRangeSubmit">{{resource.submit}}</view>
+ </view>
+ <!-- date -->
+ <view v-if="isDate">
+ <uni-datetime-picker ref="datetimepicker" :value="dateRange" type="datetimerange" return-type="timestamp" @change="datetimechange" @maskClick="timepickerclose">
+ <view></view>
+ </uni-datetime-picker>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import checkBox from '../uni-tr/table-checkbox.vue'
+
+ const resource = {
+ "reset": "閲嶇疆",
+ "search": "鎼滅储",
+ "submit": "纭畾",
+ "filter": "绛涢��",
+ "gt": "澶т簬绛変簬",
+ "lt": "灏忎簬绛変簬",
+ "date": "鏃ユ湡鑼冨洿"
+ }
+
+ const DropdownType = {
+ Select: "select",
+ Search: "search",
+ Range: "range",
+ Date: "date",
+ Timestamp: "timestamp"
+ }
+
+ export default {
+ name: 'FilterDropdown',
+ emits:['change'],
+ components: {
+ checkBox
+ },
+ options: {
+ virtualHost: true
+ },
+ props: {
+ filterType: {
+ type: String,
+ default: DropdownType.Select
+ },
+ filterData: {
+ type: Array,
+ default () {
+ return []
+ }
+ },
+ mode: {
+ type: String,
+ default: 'default'
+ },
+ map: {
+ type: Object,
+ default () {
+ return {
+ text: 'text',
+ value: 'value'
+ }
+ }
+ }
+ },
+ computed: {
+ canReset() {
+ if (this.isSearch) {
+ return this.filterValue.length > 0
+ }
+ if (this.isSelect) {
+ return this.checkedValues.length > 0
+ }
+ if (this.isRange) {
+ return (this.gtValue.length > 0 && this.ltValue.length > 0)
+ }
+ if (this.isDate) {
+ return this.dateSelect.length > 0
+ }
+ return false
+ },
+ isSelect() {
+ return this.filterType === DropdownType.Select
+ },
+ isSearch() {
+ return this.filterType === DropdownType.Search
+ },
+ isRange() {
+ return this.filterType === DropdownType.Range
+ },
+ isDate() {
+ return (this.filterType === DropdownType.Date || this.filterType === DropdownType.Timestamp)
+ }
+ },
+ watch: {
+ filters(newVal) {
+ this._copyFilters()
+ },
+ indeterminate(newVal) {
+ this.isIndeterminate = newVal
+ }
+ },
+ data() {
+ return {
+ resource,
+ enabled: true,
+ isOpened: false,
+ dataList: [],
+ filterValue: '',
+ checkedValues: [],
+ gtValue: '',
+ ltValue: '',
+ dateRange: [],
+ dateSelect: []
+ };
+ },
+ created() {
+ this._copyFilters()
+ },
+ methods: {
+ _copyFilters() {
+ let dl = JSON.parse(JSON.stringify(this.filterData))
+ for (let i = 0; i < dl.length; i++) {
+ if (dl[i].checked === undefined) {
+ dl[i].checked = false
+ }
+ }
+ this.dataList = dl
+ },
+ openPopup() {
+ this.isOpened = true
+ if (this.isDate) {
+ this.$nextTick(() => {
+ if (!this.dateRange.length) {
+ this.resetDate()
+ }
+ this.$refs.datetimepicker.show()
+ })
+ }
+ },
+ closePopup() {
+ this.isOpened = false
+ },
+ handleClose(e) {
+ this.closePopup()
+ },
+ resetDate() {
+ let date = new Date()
+ let dateText = date.toISOString().split('T')[0]
+ this.dateRange = [dateText + ' 0:00:00', dateText + ' 23:59:59']
+ },
+ onDropdown(e) {
+ this.openPopup()
+ },
+ onItemClick(e, index) {
+ let items = this.dataList
+ let listItem = items[index]
+ if (listItem.checked === undefined) {
+ items[index].checked = true
+ } else {
+ items[index].checked = !listItem.checked
+ }
+
+ let checkvalues = []
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i]
+ if (item.checked) {
+ checkvalues.push(item.value)
+ }
+ }
+ this.checkedValues = checkvalues
+ },
+ datetimechange(e) {
+ this.closePopup()
+ this.dateRange = e
+ this.dateSelect = e
+ this.$emit('change', {
+ filterType: this.filterType,
+ filter: e
+ })
+ },
+ timepickerclose(e) {
+ this.closePopup()
+ },
+ handleSelectSubmit() {
+ this.closePopup()
+ this.$emit('change', {
+ filterType: this.filterType,
+ filter: this.checkedValues
+ })
+ },
+ handleSelectReset() {
+ if (!this.canReset) {
+ return;
+ }
+ var items = this.dataList
+ for (let i = 0; i < items.length; i++) {
+ let item = items[i]
+ this.$set(item, 'checked', false)
+ }
+ this.checkedValues = []
+ this.handleSelectSubmit()
+ },
+ handleSearchSubmit() {
+ this.closePopup()
+ this.$emit('change', {
+ filterType: this.filterType,
+ filter: this.filterValue
+ })
+ },
+ handleSearchReset() {
+ if (!this.canReset) {
+ return;
+ }
+ this.filterValue = ''
+ this.handleSearchSubmit()
+ },
+ handleRangeSubmit(isReset) {
+ this.closePopup()
+ this.$emit('change', {
+ filterType: this.filterType,
+ filter: isReset === true ? [] : [parseInt(this.gtValue), parseInt(this.ltValue)]
+ })
+ },
+ handleRangeReset() {
+ if (!this.canReset) {
+ return;
+ }
+ this.gtValue = ''
+ this.ltValue = ''
+ this.handleRangeSubmit(true)
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .flex-r {
+ display: flex;
+ flex-direction: row;
+ }
+
+ .flex-f {
+ flex: 1;
+ }
+
+ .a-i-c {
+ align-items: center;
+ }
+
+ .j-c-c {
+ justify-content: center;
+ }
+
+ .icon-select {
+ width: 14px;
+ height: 16px;
+ border: solid 6px transparent;
+ border-top: solid 6px #ddd;
+ border-bottom: none;
+ background-color: #ddd;
+ background-clip: content-box;
+ box-sizing: border-box;
+ }
+
+ .icon-select.active {
+ background-color: #1890ff;
+ border-top-color: #1890ff;
+ }
+
+ .icon-search {
+ width: 12px;
+ height: 16px;
+ position: relative;
+ }
+
+ .icon-search-0 {
+ border: 2px solid #ddd;
+ border-radius: 8px;
+ width: 7px;
+ height: 7px;
+ }
+
+ .icon-search-1 {
+ position: absolute;
+ top: 8px;
+ right: 0;
+ width: 1px;
+ height: 7px;
+ background-color: #ddd;
+ transform: rotate(-45deg);
+ }
+
+ .icon-search.active .icon-search-0 {
+ border-color: #1890ff;
+ }
+
+ .icon-search.active .icon-search-1 {
+ background-color: #1890ff;
+ }
+
+ .icon-calendar {
+ color: #ddd;
+ width: 14px;
+ height: 16px;
+ }
+
+ .icon-calendar-0 {
+ height: 4px;
+ margin-top: 3px;
+ margin-bottom: 1px;
+ background-color: #ddd;
+ border-radius: 2px 2px 1px 1px;
+ position: relative;
+ }
+ .icon-calendar-0:before, .icon-calendar-0:after {
+ content: '';
+ position: absolute;
+ top: -3px;
+ width: 4px;
+ height: 3px;
+ border-radius: 1px;
+ background-color: #ddd;
+ }
+ .icon-calendar-0:before {
+ left: 2px;
+ }
+ .icon-calendar-0:after {
+ right: 2px;
+ }
+
+ .icon-calendar-1 {
+ height: 9px;
+ background-color: #ddd;
+ border-radius: 1px 1px 2px 2px;
+ }
+
+ .icon-calendar.active {
+ color: #1890ff;
+ }
+
+ .icon-calendar.active .icon-calendar-0,
+ .icon-calendar.active .icon-calendar-1,
+ .icon-calendar.active .icon-calendar-0:before,
+ .icon-calendar.active .icon-calendar-0:after {
+ background-color: #1890ff;
+ }
+
+ .uni-filter-dropdown {
+ position: relative;
+ font-weight: normal;
+ }
+
+ .dropdown-popup {
+ position: absolute;
+ top: 100%;
+ background-color: #fff;
+ box-shadow: 0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d;
+ min-width: 150px;
+ z-index: 1000;
+ }
+
+ .dropdown-popup-left {
+ left: 0;
+ }
+
+ .dropdown-popup-right {
+ right: 0;
+ }
+
+ .uni-dropdown-cover {
+ position: fixed;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ background-color: transparent;
+ z-index: 100;
+ }
+
+ .list {
+ margin-top: 5px;
+ margin-bottom: 5px;
+ }
+
+ .list-item {
+ padding: 5px 10px;
+ text-align: left;
+ }
+
+ .list-item:hover {
+ background-color: #f0f0f0;
+ }
+
+ .check {
+ margin-right: 5px;
+ }
+
+ .search-area {
+ padding: 10px;
+ }
+
+ .search-input {
+ font-size: 12px;
+ border: 1px solid #f0f0f0;
+ border-radius: 3px;
+ padding: 2px 5px;
+ min-width: 150px;
+ text-align: left;
+ }
+
+ .input-label {
+ margin: 10px 10px 5px 10px;
+ text-align: left;
+ }
+
+ .input {
+ font-size: 12px;
+ border: 1px solid #f0f0f0;
+ border-radius: 3px;
+ margin: 10px;
+ padding: 2px 5px;
+ min-width: 150px;
+ text-align: left;
+ }
+
+ .opera-area {
+ cursor: default;
+ border-top: 1px solid #ddd;
+ padding: 5px;
+ }
+
+ .opera-area .btn {
+ font-size: 12px;
+ border-radius: 3px;
+ margin: 5px;
+ padding: 4px 4px;
+ }
+
+ .btn-default {
+ border: 1px solid #ddd;
+ }
+
+ .btn-default.disable {
+ border-color: transparent;
+ }
+
+ .btn-submit {
+ background-color: #1890ff;
+ color: #ffffff;
+ }
+</style>
--
Gitblit v1.9.1