From d91c23a3dc8cb22c0a5b2bbb5a74c6aac37469b5 Mon Sep 17 00:00:00 2001 From: xuxy <1059738716@qq.com> Date: 星期三, 03 七月 2024 11:35:02 +0800 Subject: [PATCH] update 分类过滤 --- uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue | 27 ++- sub_pages/supplier/flower-manage/flower-add.vue | 78 +++++++-- manifest.json | 3 pages/home/supplier-home.vue | 2 components/tree-filter/tree-filter.vue | 354 ++++++++++++++++++++++++++++++++++++++++++++ uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue | 1 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js | 5 pages/user/supplier-user.vue | 7 8 files changed, 444 insertions(+), 33 deletions(-) diff --git a/components/tree-filter/tree-filter.vue b/components/tree-filter/tree-filter.vue new file mode 100644 index 0000000..2a31d26 --- /dev/null +++ b/components/tree-filter/tree-filter.vue @@ -0,0 +1,354 @@ +<template> + <view class="tree-filter"> + <view class="tree-filter-input" @click="show"> + <slot> + + </slot> + </view> + + <view class="tree-filter-tree-cover" v-if="isOpened" @click="handleClose"></view> + <view class="tree-filter-tree-dialog" v-if="isOpened"> + <view class="tree-filter-popper__arrow"></view> + <view class="dialog-caption"> + <view class="title-area"> + <text class="dialog-title">{{popupTitle}}</text> + </view> + <view class="dialog-close" @click="handleClose"> + <view class="dialog-close-plus" data-id="close"></view> + <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view> + </view> + </view> + <view v-if="filter" + style="margin-left:40rpx;margin-right:40rpx;;margin-top: 40rpx;border-bottom:1px solid #eee;padding-bottom:20rpx;display:flex;color:#000"> + <input v-model="search" style="height:60rpx;line-height:60rpx;color:#000" placeholder="请输入搜索内容"></input> + <view @click="()=>{search='';updateSearch()}" + style="height:60rpx;line-height:60rpx;margin-left:auto;margin-right:0rpx">清空</view> + <view @click="updateSearch" style="height:60rpx;line-height:60rpx;margin-left:auto;margin-right:0rpx">搜索 + </view> + </view> + <view> + <!-- 渲染多级树,首先确认层级? --> + <view v-if="currentLevel===-1" class="tree-filter-nodes"> + <!-- 暂时跟节点 --> + <view v-for="(item,index) of localdata" :key="item.value" class="tree-filter-node" + @click="selecteRow(item)"> + <view>{{item.label}}</view> + <view class="arrow" v-if="item.children&&item.children.length>0"> + <uni-icons type="right"></uni-icons> + + </view> + </view> + </view> + <view v-else> + <view class="tree-filter-top-titles"> + <view v-for="(item,index) of currentNodes" :key="item.value" + @click="selecteRowCurrentNodesOne(item,index)" class="tree-filter-top-title"> + <view>{{item.label || '-'}}</view> + <view class="arrow"><uni-icons type="right" style="color: lightgray;"></uni-icons></view> + </view> + <view class="tree-filter-top-title-tip"> + 请选择 + </view> + </view> + <view class="tree-filter-nodes"> + <view v-for="(item,index) of currentNodes[currentLevel].children" :key="item.value" + class="tree-filter-node" @click="selecteRow(item)"> + <view>{{item.label}}</view> + <view class="arrow" v-if="item.children&&item.children.length>0"> + <uni-icons type="right"></uni-icons> + </view> + </view> + </view> + </view> + </view> + </view> + </view> +</template> +<!-- 多级带搜索插叙功能的tree --> +<script> + export default { + name: "tree-filter", + data() { + return { + isOpened: false, + search: '', + currentLevel: -1, + currentNodes: [], //数组存储 + currentValue: {} + }; + }, + methods: { + async updateSearch() { + //todo 递归搜索下面的数据,,并标记为可展示的 + console.log('updateSearch', this.localdata) + await this.$emit('search', this.search) + // console.log('updateSearch',this.localdata) + + // setTimeout(() => { + // console.log('updateSearch2 setTimeout', this.localdata) + // //清空 + // if (this.search) { + // this.selectedClear() + // } + // if(!this.search){ + // //其他的也恢复 + // this.selectedClear() + // } + // }, 200) + }, + //数据 + selectedClear() { + //清空选择的数据 + //当前层级和当前节点? + this.currentLevel = -1 + this.currentNodes = [] + this.currentValue = {} + this.$forceUpdate() + }, + selectedSet() { + //设置处理的级别,需要第几个节点 + + }, + selecteRowCurrentNodesOne(item, index) { + //选择的是最上面的 + var lens = this.currentNodes.length - index + this.currentNodes.splice(index, lens) + this.currentLevel -= (lens + 0) + console.log(' this.currentNodes', this.currentNodes,this.currentLevel) + + }, + selecteRow(row) { + //选择某一个 + console.log('selecteRow', row) + if (row.children && row.children.length > 0) { + //选择节点 + this.currentNodes.push(row) + this.currentLevel += 1 + + } else { + //选择的是value + if (this.currentLevel === -1) { + //直接选择的 + this.currentValue = row + } else { + this.currentValue = row + + } + this.hide() + this.$emit('change', { + detail: { + value: [row] + } + }) + + + } + }, + //显示 + show() { + this.isOpened = true + setTimeout(() => { + this.$refs.pickerView.updateData({ + treeData: this._treeData, + selected: this.selected, + selectedIndex: this.selectedIndex + }) + }, 200) + this.$emit('popupopened') + }, + hide() { + this.isOpened = false + this.$emit('popupclosed') + }, + handleClose() { + this.hide() + + }, + }, + props: { + filter: { + type: Boolean, + default: true + }, + placeholder: { + type: String, + default: '请选择' + }, + localdata: { + type: [Array, Object], + default () { + return [] + } + }, + selectConfirmTitle: { + type: String, + default: '' + } + } + } +</script> + +<style lang="scss"> + .tree-filter { + .tree-filter-top-titles { + display: flex; + margin-bottom: 0rpx; + overflow-x: scroll; + flex-wrap: wrap; + padding-left: 40rpx; + padding-right: 40rpx; + padding-top: 20rpx; + + .tree-filter-top-title { + margin-right: 40rpx; + text-align: left; + // color: darkgray; + color: #333; + display: flex; + + .arrow { + margin-left: 30rpx; + } + } + + .tree-filter-top-title-tip { + margin-right: 40rpx; + text-align: left; + color: darkgray; + display: inline-block; + } + + .tree-filter-top-title::last-child { + // color: #333; + } + } + + .tree-filter-nodes { + padding-left: 40rpx; + padding-right: 40rpx; + + .tree-filter-node { + display: flex; + color: #333; + + .arrow { + margin-left: auto; + margin-right: 0rpx; + } + } + } + + .tree-filter-tree-cover { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, .4); + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: column; + z-index: 100; + } + + .tree-filter-tree-dialog { + position: fixed; + padding: 20rpx; + padding-top: 40rpx; + left: 0; + /* #ifndef APP-NVUE */ + top: 20%; + /* #endif */ + /* #ifdef APP-NVUE */ + top: 200px; + /* #endif */ + right: 0; + bottom: 0; + background-color: #FFFFFF; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: column; + z-index: 102; + overflow: hidden; + /* #ifdef APP-NVUE */ + width: 750rpx; + /* #endif */ + } + + /* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */ + /* #ifndef APP-NVUE */ + .tree-filter-popper__arrow, + .tree-filter-popper__arrow::after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 6px; + } + + .tree-filter-popper__arrow { + filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03)); + top: -6px; + left: 10%; + margin-right: 3px; + border-top-width: 0; + border-bottom-color: #EBEEF5; + } + + .tree-filter-popper__arrow::after { + content: " "; + top: 1px; + margin-left: -6px; + border-top-width: 0; + border-bottom-color: #fff; + } + + /* #endif */ + .dialog-caption { + position: relative; + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: row; + /* border-bottom: 1px solid #f0f0f0; */ + } + + .dialog-title { + /* font-weight: bold; */ + line-height: 44px; + } + + .dialog-close { + position: absolute; + top: 0; + right: 0; + bottom: 0; + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: row; + align-items: center; + padding: 0 15px; + } + + .dialog-close-plus { + width: 16px; + height: 2px; + background-color: #666; + border-radius: 2px; + transform: rotate(45deg); + } + + .dialog-close-rotate { + position: absolute; + transform: rotate(-45deg); + } + + } +</style> \ No newline at end of file diff --git a/manifest.json b/manifest.json index fef255e..8466839 100644 --- a/manifest.json +++ b/manifest.json @@ -52,7 +52,8 @@ "appid" : "wx3203fd935a6ffe09", "setting" : { "urlCheck" : false, - "es6" : true + "es6" : true, + "minified" : true }, "usingComponents" : true, "plugins" : {} diff --git a/pages/home/supplier-home.vue b/pages/home/supplier-home.vue index cf0ae89..f393031 100644 --- a/pages/home/supplier-home.vue +++ b/pages/home/supplier-home.vue @@ -19,7 +19,7 @@ <image class="user-icon" v-if="currentInfo.picture" :src="currentInfo.picture" mode="aspectFit"></image> <view class="name"> - <view class="t1">{{currentInfo.nickName || currentInfo.loginName || '-'}}<span + <view class="t1">{{ (!!currentInfo.supplierDTO?(currentInfo.supplierDTO.name):"") || currentInfo.nickName || currentInfo.loginName || '-'}}<span v-if="currentInfo.supplierDTO&¤tInfo.supplierDTO.status!=='P'"> ({{currentInfo.supplierDTO?currentInfo.supplierDTO.statusStr:''}})</span> </view> diff --git a/pages/user/supplier-user.vue b/pages/user/supplier-user.vue index 41ea330..c5ced80 100644 --- a/pages/user/supplier-user.vue +++ b/pages/user/supplier-user.vue @@ -20,7 +20,8 @@ <image class="user-icon" v-if="currentInfo.picture" :src="currentInfo.picture" mode="aspectFit"></image> <view class="name"> - <view class="t1">{{currentInfo.nickName || currentInfo.loginName || '-'}}<span + <view class="t1"> + {{ (!!currentInfo.supplierDTO?(currentInfo.supplierDTO.name):"") || currentInfo.nickName || currentInfo.loginName || '-'}}<span v-if="currentInfo.supplierDTO&¤tInfo.supplierDTO.status!=='P'"> ({{currentInfo.supplierDTO?currentInfo.supplierDTO.statusStr:''}})</span> </view> @@ -55,11 +56,11 @@ <view class="flex"> <image class="icon-clock m-r-6 m-t-2" src="../../static/common/icon-call.png"></image> <view class="name"> - 客服电话 : <span class="topic-gray">{{tel}}</span> + 客服电话 : <span class="topic-gray">{{tel}}</span> </view> </view> </view> -<!-- <view class="user-util m-t-12 " @click="callTel" v-if="selftype==='partner'"> + <!-- <view class="user-util m-t-12 " @click="callTel" v-if="selftype==='partner'"> <view class="name"> 账号: <span class="topic-gray">{{tel}}</span> </view> diff --git a/sub_pages/supplier/flower-manage/flower-add.vue b/sub_pages/supplier/flower-manage/flower-add.vue index 2bbf009..b976ee1 100644 --- a/sub_pages/supplier/flower-manage/flower-add.vue +++ b/sub_pages/supplier/flower-manage/flower-add.vue @@ -11,11 +11,19 @@ <u-icon class="m-l-a" name="arrow-right"></u-icon> </view> --> <view class="m-l-a m-r-0 flex " :class="[!dto['category']?'desc-gray':'']"> - <uni-data-picker @change="(e)=>{PickCategory(dto,e)}" placeholder="" @search="updateSearch" - :localdata="columns_categorys_picker"> + <!-- <uni-data-picker ref="picker_category" @change="(e)=>{PickCategory(dto,e)}" placeholder="" + @search="updateSearch" :filter="true" :localdata="columns_categorys_picker"> {{dto.categoryStr||dto.category || '请选择'}} - </uni-data-picker> - <u-icon class="m-l-a" name="arrow-right"></u-icon> + </uni-data-picker> --> + <tree-filter ref="picker_category" @change="(e)=>{PickCategory(dto,e)}" placeholder="" + @search="updateSearch" :filter="true" :localdata="columns_categorys_picker" + selectConfirmTitle=""> + <view class="flex"> + <view>{{dto.categoryStr||dto.category || '请选择'}}</view> + <u-icon class="m-l-a" name="arrow-right"></u-icon> + </view> + + </tree-filter> </view> </view> <view class="form-item before-line"> @@ -191,14 +199,16 @@ <view class="button-green" @click="closeParamPop">返回</view> </view> </uni-popup> - <dying318picker :picker-list="columns_categorys" ref="picker_category" @confirm="confirmPickerCategory"> - </dying318picker> + <!-- <dying318picker :picker-list="columns_categorys" ref="picker_category" @confirm="confirmPickerCategory"> + </dying318picker> --> </view> </template> <script> import environments from '@/environments' import dying318picker from '@/components/dying318-picker/Picker.vue' + import treeFilter from '@/components/tree-filter/tree-filter.vue' + import { mapState @@ -308,16 +318,31 @@ this.columns_categorys_picker = [] this.mapCategoryTree(this.columns_categorys_picker, this.columns_categorys) console.log('change updateSearch', search, this.columns_categorys_picker) + this.$refs.picker_category.selectedClear() }, async PickCategory(item, e) { console.log('PickCategory', item, e) if (e.detail.value) { - if (this.dto.category) { - await this.$message.confirm('修改分类将清空商品参数,确定修改吗') - } { - var currentnode = this.columns_categorys_dict['@' + e.detail.value[e.detail.value.length - 1] - .value] - // console.log('currentnode',currentnode,this.columns_categorys_dict,'@'+e.detail.value[e.detail.value.length - 1].value) + var currentnode = this.columns_categorys_dict['@' + e.detail.value[e.detail.value.length - 1] + .value] + let tmpe = e + if (this.dto.category && this.dto.category !== currentnode.id) { + this.$message.confirm('修改分类将清空商品参数,确定修改吗').then(async res => { + // console.log('currentnode',currentnode,this.columns_categorys_dict,'@'+e.detail.value[e.detail.value.length - 1].value) + this.dto.categoryStr = currentnode.name + this.dto.category = currentnode.id + this.dto.name = currentnode.name + this.dto.unit = currentnode.unit + this.dto.color = currentnode.color + //递归获取category的其他数据,用来做map? + this.$message.showLoading() + await this.refresh_category() + this.$message.hideLoading() + }).catch(e1 => { + console.log('this.$refs.picker_category', this.$refs.picker_category) + this.$refs.picker_category.onchange(tmpe.detail.value) + }) + } else { this.dto.categoryStr = currentnode.name this.dto.category = currentnode.id this.dto.name = currentnode.name @@ -334,7 +359,7 @@ var has = true if (arr) { var hasTrue = false - if(!this.columns_categorys_search){ + if (!this.columns_categorys_search) { hasTrue = true } for (var item of arr) { @@ -352,6 +377,7 @@ } if (item.name == this.columns_categorys_search) { has = true + hasTrue = true } this.columns_categorys_dict['@' + item.id] = item if (item.children && item.children.length > 0) { @@ -364,13 +390,28 @@ } else { tmp.children = undefined } - if (hasTrue || has) { - console.log('has ',tmp) + + if (has) { + console.log('has ', tmp, hasTrue, has) node.push(tmp) - } else { - console.log('not has ',tmp) + } + if (!has && hasTrue) { + //说明是这个节点有的,需要判断是否需要删除 + if (!tmp.children || tmp.children.length == 0) { + + } else { + console.log('has ', tmp, hasTrue, has) + node.push(tmp) + } + } + // if (hasTrue || has) { + // node.push(tmp) + + // } else { + // console.log('not has ', tmp) + // } } } @@ -568,7 +609,8 @@ } }, components: { - dying318picker + dying318picker, + treeFilter } } </script> diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue index f448352..e0aa39f 100644 --- a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue +++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue @@ -3,6 +3,7 @@ <view class="uni-data-tree-input" @click="handleInput"> <slot :options="options" :data="inputSelected" :error="errorMessage"> <view class="input-value" :class="{'input-value-border': border}"> + <text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text> <view v-else-if="loading && !isOpened" class="selected-area"> <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more> @@ -37,13 +38,13 @@ <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view> </view> </view> - <view v-if="false" - style="margin-left:40rpx;margin-right:40rpx;; border-bottom:1px solid #eee;padding-bottom:20rpx;display:flex"> + <view v-if="filter" + style="margin-left:40rpx;margin-right:40rpx;; border-bottom:1px solid #eee;padding-bottom:20rpx;display:flex;color:#000"> <input v-model="search" style="height:60rpx;line-height:60rpx;color:#000" placeholder="请输入搜索内容"></input> - <button @click="()=>{search='';updateSearch()}" - style="height:60rpx;line-height:60rpx;margin-left:auto;margin-right:0rpx">清空</button> - <button @click="updateSearch" - style="height:60rpx;line-height:60rpx;margin-left:auto;margin-right:0rpx">搜索</button> + <view @click="()=>{search='';updateSearch()}" + style="height:60rpx;line-height:60rpx;margin-left:auto;margin-right:0rpx">清空</view> + <view @click="updateSearch" + style="height:60rpx;line-height:60rpx;margin-left:auto;margin-right:0rpx">搜索</view> </view> <data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata" :preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where" @@ -112,6 +113,10 @@ type: Boolean, default: false }, + filter: { + type: Boolean, + default: false + }, clearIcon: { type: Boolean, default: true @@ -161,8 +166,8 @@ await this.$emit('search',this.search) // console.log('updateSearch',this.localdata) setTimeout(() => { - console.log('updateSearch2',this.localdata) - this.showpicker = new Date().getTime() + console.log('updateSearch2 setTimeout',this.localdata) + // this.showpicker = new Date().getTime() // this.load() this.$refs.pickerView.updateData({ treeData: this.localdata, @@ -189,7 +194,9 @@ this.load(); }, load() { + // console.log('load',this.readonly) if (this.readonly) { + // console.debug('load readonly') this._processReadonly(this.localdata, this.dataValue); return; } @@ -198,7 +205,10 @@ if (this.isLocalData) { this.loadData(); this.inputSelected = this.selected.slice(0); + console.log('load isLocalData',this.inputSelected) + } else if (this.isCloudDataList || this.isCloudDataTree) { // 回显 Cloud 数据 + // console.log('load Cloud') this.loading = true; this.getCloudDataValue().then((res) => { this.loading = false; @@ -208,6 +218,7 @@ this.errorMessage = err; }) } + // console.log('load over') }, show() { this.isOpened = true diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js index cfae22a..328a3db 100644 --- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js +++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js @@ -216,9 +216,10 @@ inputValue = inputValue[this.map.value]; } } - + this.selected = this._findNodePath(inputValue, this.localdata); - }, + console.log('_findNodePath',inputValue,this.localdata) + }, // 加载 Cloud 数据 (单列) async loadCloudDataList() { diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue index 6ebced9..10d3e29 100644 --- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue +++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue @@ -67,6 +67,7 @@ } }, created() { + console.log('created picker') if (!this.managedMode) { this.$nextTick(() => { this.loadData(); -- Gitblit v1.9.3