userSelect

This commit is contained in:
shijing 2022-10-09 08:57:12 +08:00
parent e068923bbe
commit 066b6f7f99
9 changed files with 1515 additions and 176 deletions

View File

@ -0,0 +1,124 @@
## 树形层级选择器
### 简介
为统一样式而生树形层级选择器picker弹窗形式的样式和比例参照uniapp的picker和uni-data-picker组件
* 支持单选、多选、父级选择,当然也支持单层选择
* 支持Object对象属性自定义映射
* 支持显示全部选中、部分选中、未选中三种状态
* 支持快速自定义简单样式分割线、按钮、标题、对齐等深入样式可复写css
### 使用方法
`script` 中引入组件
``` javascript
import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue"
export default {
components: {
baTreePicker
}
```
`template` 中使用组件
``` javascript
<ba-tree-picker ref="treePicker" :multiple='false' @select-change="selectChange" title="选择城市"
:localdata="listData" valueKey="value" textKey="label" childrenKey="children" />
```
`script` 中定义打开方法,和选择监听
``` javascript
methods: {
// 显示选择器
showPicker() {
this.$refs.treePicker._show();
},
//监听选择ids为数组
selectChange(ids, names) {
console.log(ids, names)
}
}
```
`template` 中调用打开
``` javascript
<view @click="showPicker">调用选择器</view>
```
### 属性
|属性名|类型|默认值|说明|
|:-|:-:|:--:|-:|
|localdata|Array|[]|源数据目前支持tree结构后续会考虑支持扁平化结构|
|valueKey|String|id|指定 Object 中 key 的值作为节点数据id|
|textKey|String|name|指定 Object 中 key 的值作为节点显示内容|
|childrenKey|String|children|指定 Object 中 key 的值作为节点子集|
|multiple|Boolean|false|是否多选,默认单选|
|selectParent|Boolean|true|是否可以选父级,默认可以|
|title|String| |标题|
|titleColor|String||标题颜色|
|confirmColor|String|#0055ff|确定按钮颜色|
|cancelColor|String|#757575|取消按钮颜色|
|switchColor|String|#666|节点切换图标颜色|
|border|Boolean|false|是否有分割线,默认无|
### 数据格式
注意必须有id、name(id可通过valueKey来配置为其它键值如value)字段,且唯一
``` json
[
{
id: 1,
name: '公司1',
children: [{
id: 11,
name: '研发部',
children: [{
id: 111,
name: '张三',
},{
id: 112,
name: '李四',
}]
},{
id: 12,
name: '综合部',
} ]
},
{
id: 2,
name: '公司2',
children: [{
id: 21,
name: '研发部',
},{
id: 22,
name: '综合部',
},{
id: 23,
name: '财务部',
}, ]
},
{
id: 3,
name: '公司3'
},
{
id: 4,
name: '公司4',
children: [{
id: 41,
name: '研发部',
}]
}
]
```
</details>
### 方法
|方法名|参数|默认值|说明|
|:-|:-:|:--:|-:|
|_show()| | |显示选择器|
|_hide()| | |隐藏选择器|

View File

@ -0,0 +1,624 @@
<!-- 树形层级选择器-->
<!-- 1支持单选多选 -->
<template>
<view>
<view class="tree-cover" :class="{'show':showDialog}" @tap="_cancel"></view>
<view class="tree-dialog" :class="{'show':showDialog}">
<view class="tree-bar">
<view class="tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">取消
</view>
<view class="tree-bar-title" :style="{'color':titleColor}">{{title}}</view>
<view class="tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c" @tap="_confirm">
{{multiple?'确定':''}}
</view>
</view>
<view class="tree-view">
<scroll-view class="tree-list" :scroll-y="true">
<block v-for="(item, index) in treeList" :key="index">
<view class="tree-item" :style="[{
paddingLeft: item.level*30 + 'rpx'
}]" :class="{
itemBorder: border === true,
show: item.isShow
}">
<view class="item-label">
<view class="item-icon uni-inline-item" @tap.stop="_onItemSwitch(item, index)">
<view v-if="!item.isLastLevel&&item.isShowChild" class="switch-on"
:style="{'border-left-color':switchColor}">
</view>
<view v-else-if="!item.isLastLevel&&!item.isShowChild" class="switch-off"
:style="{'border-top-color':switchColor}">
</view>
<view v-else class="item-last-dot" :style="{'border-top-color':switchColor}">
</view>
</view>
<view class="uni-flex-item uni-inline-item" @tap.stop="_onItemSelect(item, index)">
<view class="item-name"> {{item.name+(item.childCount?"("+item.childCount+")":'')}}
</view>
<view class="item-check" v-if="selectParent?true:item.isLastLevel">
<view class="item-check-yes" v-if="item.checkStatus==1"
:class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
<view class="item-check-yes-part"
:style="{'background-color':confirmColor}">
</view>
</view>
<view class="item-check-yes" v-else-if="item.checkStatus==2"
:class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
<view class="item-check-yes-all" :style="{'background-color':confirmColor}">
</view>
</view>
<view class="item-check-no" v-else :class="{'radio':!multiple}"
:style="{'border-color':confirmColor}"></view>
</view>
</view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
export default {
emits: ['select-change'],
name: "ba-tree-picker",
props: {
valueKey: {
type: String,
default: 'id'
},
textKey: {
type: String,
default: 'name'
},
childrenKey: {
type: String,
default: 'children'
},
localdata: {
type: Array,
default: function() {
return []
}
},
localTreeList: { //
type: Array,
default: function() {
return []
}
},
selectedData: {
type: Array,
default: function() {
return []
}
},
title: {
type: String,
default: ''
},
multiple: { //
type: Boolean,
default: true
},
selectParent: { //
type: Boolean,
default: true
},
confirmColor: { //
type: String,
default: '' // #0055ff
},
cancelColor: { //
type: String,
default: '' // #757575
},
titleColor: { //
type: String,
default: '' //
},
switchColor: { //
type: String,
default: '' // #666
},
border: { // 线
type: Boolean,
default: false
},
},
data() {
return {
showDialog: false,
treeList: []
}
},
computed: {},
methods: {
_show() {
this.showDialog = true
},
_hide() {
this.showDialog = false
},
_cancel() {
this._hide()
this.$emit("cancel", '');
},
_confirm() { //
let selectedList = []; // id
let selectedNames;
let currentLevel = -1;
this.treeList.forEach((item, index) => {
if (currentLevel >= 0 && item.level > currentLevel) {
} else {
if (item.checkStatus === 2) {
currentLevel = item.level;
selectedList.push(item.id);
selectedNames = selectedNames ? selectedNames + ' / ' + item.name : item.name;
} else {
currentLevel = -1;
}
}
})
//console.log('_confirm', selectedList);
this._hide()
this.$emit("select-change", selectedList, selectedNames);
},
//tree
_formatTreeData(list = [], level = 0, parentItem, isShowChild = true) {
let nextIndex = 0;
let parentId = -1;
let initCheckStatus = 0;
if (parentItem) {
nextIndex = this.treeList.findIndex(item => item.id === parentItem.id) + 1;
parentId = parentItem.id;
if (!this.multiple) { //
initCheckStatus = 0;
} else
initCheckStatus = parentItem.checkStatus == 2 ? 2 : 0;
}
list.forEach(item => {
let isLastLevel = true;
if (item && item[this.childrenKey]) {
let children = item[this.childrenKey];
if (Array.isArray(children) && children.length > 0) {
isLastLevel = false;
}
}
let itemT = {
id: item[this.valueKey],
name: item[this.textKey],
level,
isLastLevel,
isShow: isShowChild,
isShowChild: false,
checkStatus: initCheckStatus,
orCheckStatus: 0,
parentId,
children: item[this.childrenKey],
childCount: item[this.childrenKey] ? item[this.childrenKey].length : 0,
childCheckCount: 0,
childCheckPCount: 0
};
if (this.selectedData.indexOf(itemT.id) >= 0) {
itemT.checkStatus = 2;
itemT.orCheckStatus = 2;
itemT.childCheckCount = itemT.children ? itemT.children.length : 0;
this._onItemParentSelect(itemT, nextIndex);
}
this.treeList.splice(nextIndex, 0, itemT);
nextIndex++;
})
//console.log(this.treeList);
},
//
_onItemSwitch(item, index) {
// console.log(item)
//console.log('_itemSwitch')
if (item.isLastLevel === true) {
return;
}
item.isShowChild = !item.isShowChild;
if (item.children) {
this._formatTreeData(item.children, item.level + 1, item);
item.children = undefined;
} else {
this._onItemChildSwitch(item, index);
}
},
_onItemChildSwitch(item, index) {
//console.log('_onItemChildSwitch')
const firstChildIndex = index + 1;
if (firstChildIndex > 0)
for (var i = firstChildIndex; i < this.treeList.length; i++) {
let itemChild = this.treeList[i];
if (itemChild.level > item.level) {
if (item.isShowChild) {
if (itemChild.parentId === item.id) {
itemChild.isShow = item.isShowChild;
if (!itemChild.isShow) {
itemChild.isShowChild = false;
}
}
} else {
itemChild.isShow = item.isShowChild;
itemChild.isShowChild = false;
}
} else {
return;
}
}
},
//
_onItemSelect(item, index) {
//console.log('_onItemSelect')
//console.log(item)
if (!this.multiple) { //
item.checkStatus = item.checkStatus == 0 ? 2 : 0;
this.treeList.forEach((v, i) => {
if (i != index) {
this.treeList[i].checkStatus = 0
} else {
this.treeList[i].checkStatus = 2
}
})
let selectedList = [];
let selectedNames;
selectedList.push(item.id);
selectedNames = item.name;
this._hide()
this.$emit("select-change", selectedList, selectedNames);
return
}
let oldCheckStatus = item.checkStatus;
switch (oldCheckStatus) {
case 0:
item.checkStatus = 2;
item.childCheckCount = item.childCount;
item.childCheckPCount = 0;
break;
case 1:
case 2:
item.checkStatus = 0;
item.childCheckCount = 0;
item.childCheckPCount = 0;
break;
default:
break;
}
//
this._onItemChildSelect(item, index);
//
this._onItemParentSelect(item, index, oldCheckStatus);
},
_onItemChildSelect(item, index) {
//console.log('_onItemChildSelect')
let allChildCount = 0;
if (item.childCount && item.childCount > 0) {
index++;
while (index < this.treeList.length && this.treeList[index].level > item.level) {
let itemChild = this.treeList[index];
itemChild.checkStatus = item.checkStatus;
if (itemChild.checkStatus == 2) {
itemChild.childCheckCount = itemChild.childCount;
itemChild.childCheckPCount = 0;
} else if (itemChild.checkStatus == 0) {
itemChild.childCheckCount = 0;
itemChild.childCheckPCount = 0;
}
// console.log('>>>>index', index, 'item', itemChild.name, ' status', itemChild
// .checkStatus)
index++;
}
}
},
_onItemParentSelect(item, index, oldCheckStatus) {
//console.log('_onItemParentSelect')
//console.log(item)
const parentIndex = this.treeList.findIndex(itemP => itemP.id == item.parentId);
//console.log('parentIndex' + parentIndex)
if (parentIndex >= 0) {
let itemParent = this.treeList[parentIndex];
let count = itemParent.childCheckCount;
let oldCheckStatusParent = itemParent.checkStatus;
if (oldCheckStatus == 1) {
itemParent.childCheckPCount -= 1;
} else if (oldCheckStatus == 2) {
itemParent.childCheckCount -= 1;
}
if (item.checkStatus == 1) {
itemParent.childCheckPCount += 1;
} else if (item.checkStatus == 2) {
itemParent.childCheckCount += 1;
}
if (itemParent.childCheckCount <= 0 && itemParent.childCheckPCount <= 0) {
itemParent.childCheckCount = 0;
itemParent.childCheckPCount = 0;
itemParent.checkStatus = 0;
} else if (itemParent.childCheckCount >= itemParent.childCount) {
itemParent.childCheckCount = itemParent.childCount;
itemParent.childCheckPCount = 0;
itemParent.checkStatus = 2;
} else {
itemParent.checkStatus = 1;
}
//console.log('itemParent', itemParent)
this._onItemParentSelect(itemParent, parentIndex, oldCheckStatusParent);
}
},
//
_reTreeList() {
this.treeList.forEach((v, i) => {
this.treeList[i].checkStatus = v.orCheckStatus
})
},
_initTree() {
this.treeList = [];
this._formatTreeData(this.localdata);
}
},
watch: {
localdata() {
this._initTree();
},
localTreeList() {
this.treeList = this.localTreeList;
}
},
mounted() {
this._initTree();
}
}
</script>
<style scoped>
.tree-cover {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
z-index: 100;
background-color: rgba(0, 0, 0, .4);
opacity: 0;
transition: all 0.3s ease;
visibility: hidden;
}
.tree-cover.show {
visibility: visible;
opacity: 1;
}
.tree-dialog {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
background-color: #fff;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
z-index: 1000;
top: 20%;
transition: all 0.3s ease;
transform: translateY(100%);
}
.tree-dialog.show {
transform: translateY(0);
}
.tree-bar {
/* background-color: #fff; */
height: 90rpx;
padding-left: 25rpx;
padding-right: 25rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-bottom-width: 1rpx !important;
border-bottom-style: solid;
border-bottom-color: #f5f5f5;
font-size: 32rpx;
color: #757575;
line-height: 1;
}
.tree-bar-confirm {
color: #0055ff;
padding: 15rpx;
}
.tree-bar-title {}
.tree-bar-cancel {
color: #757575;
padding: 15rpx;
}
.tree-view {
flex: 1;
padding: 20rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
overflow: hidden;
height: 100%;
}
.tree-list {
flex: 1;
height: 100%;
overflow: hidden;
}
.tree-item {
display: flex;
justify-content: space-between;
align-items: center;
line-height: 1;
height: 0;
opacity: 0;
transition: 0.2s;
overflow: hidden;
}
.tree-item.show {
height: 90rpx;
opacity: 1;
}
.tree-item.showchild:before {
transform: rotate(90deg);
}
.tree-item.last:before {
opacity: 0;
}
.uni-flex-item{
display: flex;
line-height: 40px;
}
.switch-on {
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 15rpx solid #666;
}
.switch-off {
width: 0;
height: 0;
border-bottom: 10rpx solid transparent;
border-top: 10rpx solid transparent;
border-left: 15rpx solid #666;
}
.item-last-dot {
position: absolute;
width: 10rpx;
height: 10rpx;
border-radius: 100%;
background: #666;
}
.item-icon {
width: 26rpx;
height: 26rpx;
margin-right: 8rpx;
padding-right: 20rpx;
padding-left: 20rpx;
}
.item-label {
flex: 1;
display: flex;
align-items: center;
height: 100%;
line-height: 1.2;
}
.item-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 450rpx;
}
.item-check {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
.item-check-yes,
.item-check-no {
width: 20px;
height: 20px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
border-top-width: 1rpx;
border-left-width: 1rpx;
border-bottom-width: 1rpx;
border-right-width: 1rpx;
border-style: solid;
border-color: #0055ff;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.item-check-yes-part {
width: 12px;
height: 12px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
background-color: #0055ff;
}
.item-check-yes-all {
margin-bottom: 5px;
border: 2px solid #007aff;
border-left: 0;
border-top: 0;
height: 12px;
width: 6px;
transform-origin: center;
/* #ifndef APP-NVUE */
transition: all 0.3s;
/* #endif */
transform: rotate(45deg);
}
.item-check .radio {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.item-check .radio .item-check-yes-b {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.hover-c {
opacity: 0.6;
}
.itemBorder {
border-bottom: 1px solid #e5e5e5;
}
</style>

View File

@ -45,13 +45,6 @@
"enablePullDownRefresh": false
}
},
{
"path": "pages/home/employeeSelect",
"style": {
"navigationBarTitleText": "曲阳金隅EHS",
"navigationStyle": "custom"
}
},
{
"path": "pages/home/list/ticket",
"style": {

View File

@ -0,0 +1,649 @@
<!-- 树形层级选择器-->
<!-- 1支持单选多选 -->
<template>
<view>
<view class="tree-cover" :class="{'show':showDialog}" @tap="_cancel"></view>
<view class="tree-dialog" :class="{'show':showDialog}">
<view class="tree-bar">
<view class="tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">取消
</view>
<view class="tree-bar-title" :style="{'color':titleColor}">{{title}}</view>
<view class="tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c" @tap="_confirm">
{{multiple?'确定':''}}
</view>
</view>
<view class="tree-view">
<scroll-view class="tree-list" :scroll-y="true">
<block v-for="(item, index) in treeList" :key="index">
<view class="tree-item" :style="[{
paddingLeft: item.level*30 + 'rpx'
}]" :class="{
itemBorder: border === true,
show: item.isShow
}">
<view class="item-label">
<view class="item-icon uni-inline-item" @tap.stop="_onItemSwitch(item, index)">
<view v-if="!item.isLastLevel&&item.isShowChild" class="switch-on"
:style="{'border-left-color':switchColor}">
</view>
<view v-else-if="!item.isLastLevel&&!item.isShowChild" class="switch-off"
:style="{'border-top-color':switchColor}">
</view>
<view v-else class="item-last-dot" :style="{'border-top-color':switchColor}">
</view>
</view>
<view class="uni-flex-item uni-inline-item" @tap.stop="_onItemSelect(item, index)">
<view class="item-name"> {{item.name+(item.childCount?"("+item.childCount+")":'')}}
</view>
<view class="item-check" v-if="selectParent?true:item.isLastLevel">
<view class="item-check-yes" v-if="item.checkStatus==1"
:class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
<view class="item-check-yes-part"
:style="{'background-color':confirmColor}">
</view>
</view>
<view class="item-check-yes" v-else-if="item.checkStatus==2"
:class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
<view class="item-check-yes-all" :style="{'background-color':confirmColor}">
</view>
</view>
<view class="item-check-no" v-else :class="{'radio':!multiple}"
:style="{'border-color':confirmColor}"></view>
</view>
</view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
export default {
emits: ['select-change'],
name: "ba-tree-picker",
props: {
valueKey: {
type: String,
default: 'id'
},
textKey: {
type: String,
default: 'name'
},
childrenKey: {
type: String,
default: 'children'
},
localdata: {
type: Array,
default: function() {
return []
}
},
localTreeList: { //
type: Array,
default: function() {
return []
}
},
selectedData: {
type: Array,
default: function() {
return []
}
},
title: {
type: String,
default: ''
},
multiple: { //
type: Boolean,
default: true
},
selectParent: { //
type: Boolean,
default: true
},
confirmColor: { //
type: String,
default: '' // #0055ff
},
cancelColor: { //
type: String,
default: '' // #757575
},
titleColor: { //
type: String,
default: '' //
},
switchColor: { //
type: String,
default: '' // #666
},
border: { // 线
type: Boolean,
default: false
},
},
data() {
return {
showDialog: false,
treeList: []
}
},
computed: {},
methods: {
_show() {
this.showDialog = true
},
_hide() {
this.showDialog = false
},
_cancel() {
this._hide()
this.$emit("cancel", '');
},
_confirm() { //
let selectedList = []; // id
let selectedNames;
let currentLevel = -1;
this.treeList.forEach((item, index) => {
if (currentLevel >= 0 && item.level > currentLevel) {
} else {
if (item.checkStatus === 2) {
currentLevel = item.level;
selectedList.push(item.id);
selectedNames = selectedNames ? selectedNames + ' / ' + item.name : item.name;
} else {
currentLevel = -1;
}
}
})
//console.log('_confirm', selectedList);
this._hide()
this.$emit("select-change", selectedList, selectedNames);
},
//tree
_formatTreeData(list = [], level = 0, parentItem, isShowChild = true) {
let nextIndex = 0;
let parentId = -1;
let initCheckStatus = 0;
if (parentItem) {
nextIndex = this.treeList.findIndex(item => item.id === parentItem.id) + 1;
parentId = parentItem.id;
if (!this.multiple) { //
initCheckStatus = 0;
} else
initCheckStatus = parentItem.checkStatus == 2 ? 2 : 0;
}
list.forEach(item => {
let isLastLevel = true;
if (item && item[this.childrenKey]) {
let children = item[this.childrenKey];
if (Array.isArray(children)) {
isLastLevel = false;
}
}
let itemT = {
id: item[this.valueKey],
name: item[this.textKey],
level,
isLastLevel,
isShow: isShowChild,
isShowChild: false,
checkStatus: initCheckStatus,
orCheckStatus: 0,
parentId,
children: item[this.childrenKey],
childCount: item[this.childrenKey] ? item[this.childrenKey].length : 0,
childCheckCount: 0,
childCheckPCount: 0
};
if (this.selectedData.indexOf(itemT.id) >= 0) {
itemT.checkStatus = 2;
itemT.orCheckStatus = 2;
itemT.childCheckCount = itemT.children ? itemT.children.length : 0;
this._onItemParentSelect(itemT, nextIndex);
}
this.treeList.splice(nextIndex, 0, itemT);
nextIndex++;
})
//console.log(this.treeList);
},
//
_onItemSwitch(item, index) {
// console.log(item)
//console.log('_itemSwitch')
if (item.isLastLevel === true) {
return;
}
item.isShowChild = !item.isShowChild;
if (item.children) {
this._formatTreeData(item.children, item.level + 1, item);
item.children = undefined;
} else {
this._onItemChildSwitch(item, index);
}
},
/* _onItemSwitch(item, index) {
if (item.isLastLevel === true) {
return;
}
if(!this.selectParent){
let that=this;
if(that.localdata[index].children.length==1){
that.$u.api.userList({page: 0,belong_dept:item.id}).then(res => {
item.children = res;
that.localdata[index].children = res;
that.treeList = [];
that._formatTreeData(that.localdata);
item.isShowChild = !item.isShowChild;
that._onItemChildSwitch(that.localdata[index], index);
})
}
}
// if (item.children) {
// this._formatTreeData(item.children, item.level + 1, item);
// item.children = undefined;
// } else {
// this._onItemChildSwitch(item, index);
// }
}, */
_onItemChildSwitch(item, index) {
//console.log('_onItemChildSwitch')
const firstChildIndex = index + 1;
if (firstChildIndex > 0)
for (var i = firstChildIndex; i < this.treeList.length; i++) {
let itemChild = this.treeList[i];
if (itemChild.level > item.level) {
if (item.isShowChild) {
if (itemChild.parentId === item.id) {
itemChild.isShow = item.isShowChild;
if (!itemChild.isShow) {
itemChild.isShowChild = false;
}
}
} else {
itemChild.isShow = item.isShowChild;
itemChild.isShowChild = false;
}
} else {
return;
}
}
},
//
_onItemSelect(item, index) {
//console.log('_onItemSelect')
//console.log(item)
if (!this.multiple) { //
item.checkStatus = item.checkStatus == 0 ? 2 : 0;
this.treeList.forEach((v, i) => {
if (i != index) {
this.treeList[i].checkStatus = 0
} else {
this.treeList[i].checkStatus = 2
}
})
let selectedList = [];
let selectedNames;
selectedList.push(item.id);
selectedNames = item.name;
this._hide()
this.$emit("select-change", selectedList, selectedNames);
return
}
let oldCheckStatus = item.checkStatus;
switch (oldCheckStatus) {
case 0:
item.checkStatus = 2;
item.childCheckCount = item.childCount;
item.childCheckPCount = 0;
break;
case 1:
case 2:
item.checkStatus = 0;
item.childCheckCount = 0;
item.childCheckPCount = 0;
break;
default:
break;
}
//
this._onItemChildSelect(item, index);
//
this._onItemParentSelect(item, index, oldCheckStatus);
},
_onItemChildSelect(item, index) {
//console.log('_onItemChildSelect')
let allChildCount = 0;
if (item.childCount && item.childCount > 0) {
index++;
while (index < this.treeList.length && this.treeList[index].level > item.level) {
let itemChild = this.treeList[index];
itemChild.checkStatus = item.checkStatus;
if (itemChild.checkStatus == 2) {
itemChild.childCheckCount = itemChild.childCount;
itemChild.childCheckPCount = 0;
} else if (itemChild.checkStatus == 0) {
itemChild.childCheckCount = 0;
itemChild.childCheckPCount = 0;
}
// console.log('>>>>index', index, 'item', itemChild.name, ' status', itemChild
// .checkStatus)
index++;
}
}
},
_onItemParentSelect(item, index, oldCheckStatus) {
//console.log('_onItemParentSelect')
//console.log(item)
const parentIndex = this.treeList.findIndex(itemP => itemP.id == item.parentId);
//console.log('parentIndex' + parentIndex)
if (parentIndex >= 0) {
let itemParent = this.treeList[parentIndex];
let count = itemParent.childCheckCount;
let oldCheckStatusParent = itemParent.checkStatus;
if (oldCheckStatus == 1) {
itemParent.childCheckPCount -= 1;
} else if (oldCheckStatus == 2) {
itemParent.childCheckCount -= 1;
}
if (item.checkStatus == 1) {
itemParent.childCheckPCount += 1;
} else if (item.checkStatus == 2) {
itemParent.childCheckCount += 1;
}
if (itemParent.childCheckCount <= 0 && itemParent.childCheckPCount <= 0) {
itemParent.childCheckCount = 0;
itemParent.childCheckPCount = 0;
itemParent.checkStatus = 0;
} else if (itemParent.childCheckCount >= itemParent.childCount) {
itemParent.childCheckCount = itemParent.childCount;
itemParent.childCheckPCount = 0;
itemParent.checkStatus = 2;
} else {
itemParent.checkStatus = 1;
}
//console.log('itemParent', itemParent)
this._onItemParentSelect(itemParent, parentIndex, oldCheckStatusParent);
}
},
//
_reTreeList() {
this.treeList.forEach((v, i) => {
this.treeList[i].checkStatus = v.orCheckStatus
})
},
_initTree() {
this.treeList = [];
this._formatTreeData(this.localdata);
}
},
watch: {
localdata() {
this._initTree();
},
localTreeList() {
this.treeList = this.localTreeList;
}
},
mounted() {
this._initTree();
}
}
</script>
<style scoped>
.tree-cover {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
z-index: 100;
background-color: rgba(0, 0, 0, .4);
opacity: 0;
transition: all 0.3s ease;
visibility: hidden;
}
.tree-cover.show {
visibility: visible;
opacity: 1;
}
.tree-dialog {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
background-color: #fff;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
z-index: 1000;
top: 20%;
transition: all 0.3s ease;
transform: translateY(100%);
}
.tree-dialog.show {
transform: translateY(0);
}
.tree-bar {
/* background-color: #fff; */
height: 90rpx;
padding-left: 25rpx;
padding-right: 25rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-bottom-width: 1rpx !important;
border-bottom-style: solid;
border-bottom-color: #f5f5f5;
font-size: 32rpx;
color: #757575;
line-height: 1;
}
.tree-bar-confirm {
color: #0055ff;
padding: 15rpx;
}
.tree-bar-title {}
.tree-bar-cancel {
color: #757575;
padding: 15rpx;
}
.tree-view {
flex: 1;
padding: 20rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
overflow: hidden;
height: 100%;
}
.tree-list {
flex: 1;
height: 100%;
overflow: hidden;
}
.tree-item {
display: flex;
justify-content: space-between;
align-items: center;
line-height: 1;
height: 0;
opacity: 0;
transition: 0.2s;
overflow: hidden;
}
.tree-item.show {
height: 90rpx;
opacity: 1;
}
.tree-item.showchild:before {
transform: rotate(90deg);
}
.tree-item.last:before {
opacity: 0;
}
.uni-flex-item{
display: flex;
line-height: 40px;
}
.switch-on {
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 15rpx solid #666;
}
.switch-off {
width: 0;
height: 0;
border-bottom: 10rpx solid transparent;
border-top: 10rpx solid transparent;
border-left: 15rpx solid #666;
}
.item-last-dot {
position: absolute;
width: 10rpx;
height: 10rpx;
border-radius: 100%;
/* background: #666; */
}
.item-icon {
width: 26rpx;
height: 26rpx;
margin-right: 8rpx;
padding-right: 20rpx;
padding-left: 20rpx;
}
.item-label {
flex: 1;
display: flex;
align-items: center;
height: 100%;
line-height: 1.2;
}
.item-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 450rpx;
}
.item-check {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
.item-check-yes,
.item-check-no {
width: 20px;
height: 20px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
border-top-width: 1rpx;
border-left-width: 1rpx;
border-bottom-width: 1rpx;
border-right-width: 1rpx;
border-style: solid;
border-color: #0055ff;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.item-check-yes-part {
width: 12px;
height: 12px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
background-color: #0055ff;
}
.item-check-yes-all {
margin-bottom: 5px;
border: 2px solid #007aff;
border-left: 0;
border-top: 0;
height: 12px;
width: 6px;
transform-origin: center;
/* #ifndef APP-NVUE */
transition: all 0.3s;
/* #endif */
transform: rotate(45deg);
}
.item-check .radio {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.item-check .radio .item-check-yes-b {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.hover-c {
opacity: 0.6;
}
.itemBorder {
border-bottom: 1px solid #e5e5e5;
}
</style>

View File

@ -1,103 +0,0 @@
<template>
<view>
<view class="back">上一级</view>
<view>{{nowRouter}}</view>
<view class="deptWrap">
<view v-for="item in subDept" :key="item.id" @click="toSub(item)">
<image style="width: 50upx;height: 50upx;"></image>
<text>{{item.name}}</text>
</view>
<view v-for="user in userList" :key="user.id">{{user.name}}</view>
</view>
</view>
</template>
<script>
var that;
export default {
name: "emplyeeIndex",
data() {
return {
depRange: [],
subDept:[],//
userList:[],//
nowRouter:''
}
},
onShow() {
this.getdept();
},
methods: {
//dept
getdept() {
let that = this;
that.$u.api.deptList({page: 0}).then(res => {
that.subDept = that.depRange = that.redata(res);
debugger;
console.log(that.depRange);
debugger;
})
},
toSub(item){//id
this.nowRouter = item.name;
if(item.children){
debugger;
console.log(item)
this.subDept = item.children;
this.getUseList(item.id);
}
},
//
getUseList(id) {
this.$u.api.userList({page: 0,belong_dept:id}).then(res => {
debugger;
this.userList = res
})
},
redata(postList) {
let posts = [];
postList.forEach((item) => {
let obj = new Object();
obj = {
...item
};
obj.value = item.id;
obj.text = item.name;
obj.parentId = item.parent;
posts.push(obj);
});
let obj = posts.reduce((res, v) => ((res[v.id] = v), res), {}); //Object
let arr = [];
for (let item of posts) {
if (item.parentId == null) {
arr.push(item);
continue;
}
let parent = obj[item.parentId];
parent.children = parent.children ? parent.children : [];
parent.children.push(item);
}
console.log(arr);
return arr;
},
onnodeclick(e) {
console.log(e);
},
onpopupopened(e) {
console.log('popupopened');
},
onpopupclosed(e) {
console.log('popupclosed');
},
onchange(e) {
console.log('onchange:', e);
},
}
}
</script>
<style>
</style>

View File

@ -73,37 +73,37 @@
<text class="star">*</text>
<text class="form-left-text">业务部门</text>
</view>
<view class="form-right">
<uni-data-picker placeholder="请选择业务部门" popup-title="请选择业务部门" :localdata="depRange"
v-model="formData.dept_bus" >
</uni-data-picker>
<view class="form-right" style="position: relative;">
<ba-tree-picker ref="treePicker" :multiple='false' @select-change="selectChange" title="选择业务部门"
:localdata="depRange" valueKey="id" textKey="name" childrenKey="children"/>
<text type="text">{{dept_bus_name}}</text>
<uni-icons style="position: absolute; right: 0;" @click="showPicker" type="arrowright" color="#999999"/>
</view>
</view>
<view class="form-item border-bottom">
<view class="form-left" @click="selectUser">
<text class="star">*</text>
<text class="form-left-text">部门协调员</text>
</view>
<view class="form-right">
<uni-data-select v-model="formData.coordinator" :localdata="userRange">
</uni-data-select>
<view class="form-right" style="position: relative;">
<ba-tree-picker ref="dcoordinator_Picker" :multiple='false' @select-change="select_coordinator_Change" title="选择部门协调员"
:localdata="userRange" valueKey="id" textKey="name" childrenKey="children" :selectParent='false'/>
<text type="text">{{dcoordinator_name}}</text>
<uni-icons style="position: absolute; right: 0;" @click="showDcoordinatorPicker" type="arrowright" color="#999999"/>
</view>
</view>
<view class="form-item border-bottom">
<view class="form-left">
<text class="star">*</text>
<text class="form-left-text">属地部门</text>
</view>
<view class="form-right">
<uni-data-picker placeholder="请选择属地部门" popup-title="请选择属地部门" :localdata="depRange"
v-model="formData.dept_ter" @change="onchange" @nodeclick="onnodeclick"
@popupopened="onpopupopened" @popupclosed="onpopupclosed">
</uni-data-picker>
<view class="form-right" style="position: relative;">
<ba-tree-picker ref="dept_ter_Picker" :multiple='false' @select-change="select_dept_ter_Change" title="请选择属地部门"
:localdata="depRange" valueKey="id" textKey="name" childrenKey="children" />
<text type="text">{{dept_ter_name}}</text>
<uni-icons style="position: absolute; right: 0;" @click="showDeptTerPicker" type="arrowright" color="#999999"/>
</view>
</view>
<view class="btn" v-if="showBtns">
<button type="primary" class="save-btn" @click="saveSubmit">下一步</button>
</view>
@ -114,12 +114,16 @@
<script>
var that;
import baTreePicker from "../../comm/ba-tree-picker/ba-tree-picker.vue";
import nonNullCheck from '../../../utils/nonNullCheck.js';
import resetData from '../../../utils/common.js';
export default {
name: "operation",
components: {
baTreePicker
},
data() {
return {
formData: {
name: '', //
// state: '', //
@ -133,6 +137,9 @@
dept_bus: '', //
coordinator: '', //
},
dept_bus_name:'请选择业务部门',
dept_ter_name:'请选择属地部门',
dcoordinator_name:'请选择部门协调员',
userRange: [],
vchannelOptions: [],
//
@ -156,7 +163,6 @@
}
},
onLoad(params) {
debugger;
if(params.operationId){
this.operationId = params.operationId;
this.type = params.type;
@ -171,13 +177,40 @@
}
},
onShow() {
this.getdept();
this.getRange();
this.getUserRange();
this.range = [];
},
methods: {
//
showPicker() {
this.$refs.treePicker._show();
},
showDeptTerPicker(){
this.$refs.dept_ter_Picker._show();
},
showDcoordinatorPicker(){
this.$refs.dcoordinator_Picker._show();
},
cancel(){
this.$refs.treePicker._hide();
},
//ids
selectChange(ids, names) {
// debugger;
// console.log(ids, names);
this.formData.dept_bus = ids[0];
this.dept_bus_name = names;
},
select_coordinator_Change(ids, names){
this.formData.coordinator = ids[0];
this.dcoordinator_name = names;
},
select_dept_ter_Change(ids, names){
this.formData.dept_ter = ids[0];
this.dept_ter_name = names;
},
//operation
getOperation() {
debugger;
@ -231,9 +264,7 @@
getdept() {
let that = this;
that.$u.api.deptList({page: 0}).then(res => {
that.depRange = that.redata(res);
console.log(that.depRange)
that.depRange = resetData(res);
})
},
//
@ -252,47 +283,19 @@
},
//
getUserRange() {
this.$u.api.userList({page: 0}).then(res => {
let user = [];
let obj = {};
res.forEach(item => {
obj = {value: null,text: ''};
obj.value = item.id;
obj.text = item.name;
user.push(obj);
})
this.userRange = user
let that = this;
that.$u.api.deptList({page: 0}).then(res => {
that.userRange = resetData(res);
let userRange = that.userRange[0];
let depts = userRange.children;
for (let i=0;i<depts.length;i++){
that.$u.api.userList({page: 0,belong_dept:depts[i].id}).then(res => {
depts[i].children = res;
})
}
userRange.children = depts;
})
},
redata(postList) {
let posts = [];
postList.forEach((item) => {
let obj = new Object();
obj = {
...item
};
obj.value = item.id;
obj.text = item.name;
obj.parentId = item.parent;
posts.push(obj);
});
let obj = posts.reduce((res, v) => ((res[v.id] = v), res), {}); //Object
let arr = [];
for (let item of posts) {
if (item.parentId == null) {
arr.push(item);
continue;
}
let parent = obj[item.parentId];
parent.children = parent.children ? parent.children : [];
parent.children.push(item);
}
console.log(arr);
return arr;
},
/* 参数验证 */
paramsCheck() {
if (!nonNullCheck(this.formData.name)) {

View File

@ -52,9 +52,14 @@
<!-- <text class="star">*</text> -->
<text class="form-left-text">所属部门</text>
</view>
<view class="form-right">
<uni-data-picker placeholder="请选择所属部门" popup-title="请选择所属部门" :localdata="depRange" v-model="formData.belong_dept">
</uni-data-picker>
<view class="form-right" style="position: relative;">
<ba-tree-picker ref="dept_ter_Picker" :multiple='false' @select-change="select_dept_ter_Change" title="请选择属地部门"
:localdata="depRange" valueKey="id" textKey="name" childrenKey="children" />
<text type="text">{{dept_ter_name}}</text>
<uni-icons style="position: absolute; right: 0;" @click="showDeptTerPicker" type="arrowright" color="#999999"/>
<!-- <uni-data-picker placeholder="请选择所属部门" popup-title="请选择所属部门" :localdata="depRange" v-model="formData.belong_dept">
</uni-data-picker> -->
</view>
</view>
@ -78,8 +83,12 @@
<script>
import nonNullCheck from '../../../utils/nonNullCheck.js';
import baTreePicker from "../../comm/ba-tree-picker/ba-tree-picker.vue";
export default {
name: "rpjCreate",
components: {
baTreePicker
},
data() {
return {
formData: {
@ -91,6 +100,7 @@
belong_dept: null, //
rparty: null, //
},
dept_ter_name:'请选择所属部门',
showBtns:false,
datetimerange: [],
depRange: [],
@ -141,6 +151,13 @@
this.getRpartyList();
},
methods: {
showDeptTerPicker(){
this.$refs.dept_ter_Picker._show();
},
select_dept_ter_Change(ids, names){
this.formData.dept_ter = ids[0];
this.dept_ter_name = names;
},
//dept
getdept() {
let that = this;

View File

@ -40,9 +40,9 @@ const store = new Vuex.Store({
// vuex_host: 'http://222.222.144.147:6013',
// vuex_api: 'http://222.222.144.147:6013/api',
// vuex_apifile: 'http://222.222.144.147:6013/api/file/',
vuex_host: 'http://10.99.5.79:20309',
vuex_api: 'http://10.99.5.79:20309/api',
vuex_apifile: 'http://10.99.5.79:20309/api/file/',
vuex_host: 'http://222.222.144.147:6013',
vuex_api: 'http://222.222.144.147:6013/api',
vuex_apifile: 'http://222.222.144.147:6013/api/file/',
},
mutations: {
$uStore(state, payload) {

32
utils/common.js Normal file
View File

@ -0,0 +1,32 @@
function resetData(params) {
let posts = [];
params.forEach((item) => {
let obj = new Object();
obj = {
...item
};
obj.value = item.id;
obj.text = item.name;
obj.parentId = item.parent;
posts.push(obj);
});
let obj = posts.reduce((res, v) => ((res[v.id] = v), res), {}); //Object
let arr = [];
for (let item of posts) {
if (item.parentId == null) {
arr.push(item);
continue;
}
let parent = obj[item.parentId];
parent.children = parent.children ? parent.children : [];
parent.children.push(item);
}
return arr;
}
export default resetData;