selectPeople.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <template>
  2. <u-popup :show="show" @close="show=false" :closeable='true'>
  3. <view class="popup">
  4. <view class="header">
  5. 请选择
  6. </view>
  7. <view class="search">
  8. <u-search placeholder="名称" v-model="keyword" @search='onClickButton' @custom='onClickButton'></u-search>
  9. </view>
  10. <view class="breadcrumb">
  11. <span class="breadcrumb_c" v-for="(item, index) in breadcrumbList" :key="item.id"
  12. @click="todept(item, index)">
  13. {{ item.name }}
  14. <span v-if="index !== breadcrumbList.length - 1">/</span>
  15. </span>
  16. </view>
  17. <view class="main">
  18. <view class="tree" v-if="treeList.length>0">
  19. <view class="boxs" v-for="item in treeList" :key="item.id">
  20. <checkbox style="width: 50rpx;" @click="change(item)" :checked="item.checked"
  21. :disabled="item.disabled" />
  22. <view style="display: flex">
  23. <view @click="change(item)">
  24. <span>
  25. {{ item.name }}&nbsp;&nbsp; ({{ item.children.length }})
  26. </span>
  27. <span v-if="pLabel">- {{ item.parentName }}</span>
  28. </view>
  29. <span @click="details(item)" v-if="item.children.length > 0"
  30. style="font-size: 28rpx; color: #2561ef">下级</span>
  31. </view>
  32. </view>
  33. </view>
  34. <u-empty mode="data" v-else icon="http://cdn.uviewui.com/uview/empty/data.png"></u-empty>
  35. </view>
  36. <div class="bottom">
  37. <div class="checkAll">
  38. <div style="color: #2561ef">
  39. 已选择{{ suredata.length }}项
  40. </div>
  41. </div>
  42. <div class="sure" @click="sure">确认</div>
  43. </div>
  44. </view>
  45. </u-popup>
  46. </template>
  47. <script>
  48. export default {
  49. name: "selectPeople",
  50. props: {
  51. value: {
  52. type: String,
  53. default: ''
  54. },
  55. label: {
  56. type: String,
  57. default: ''
  58. },
  59. checkof: {
  60. type: Boolean,
  61. default: false
  62. },
  63. src: {
  64. type: String,
  65. default: '/sys/dept/sysUserTreeInfo'
  66. }
  67. },
  68. data() {
  69. return {
  70. show: false,
  71. pLabel: false,
  72. keyword: "",
  73. suredata: [],
  74. breadcrumbList: [],
  75. treeList: [],
  76. deptList: []
  77. };
  78. },
  79. methods: {
  80. sure() {
  81. let departmentId = [];
  82. let departmentName = [];
  83. this.suredata.forEach((x) => {
  84. departmentId.push(x.id);
  85. departmentName.push(x.name);
  86. });
  87. this.$emit("update:value", departmentId.toString());
  88. this.$emit("update:label", departmentName.toString());
  89. this.$emit("selectPeople", this.suredata);
  90. this.show = false
  91. },
  92. onClickButton() {
  93. this.check(this.keyword);
  94. if (this.keyword) {
  95. this.pLabel = true;
  96. } else {
  97. this.pLabel = false;
  98. }
  99. this.treeList = this.check(this.keyword);
  100. },
  101. check(name, nodes = this.deptList, arr = []) {
  102. for (let item of nodes) {
  103. if (item.name.indexOf(name) > -1) {
  104. arr.push(item);
  105. }
  106. if (item.children && item.children.length)
  107. this.check(name, item.children, arr);
  108. }
  109. return name ? arr : this.deptList[0].children;
  110. },
  111. init() {
  112. this.breadcrumbList = []
  113. this.getDept()
  114. },
  115. async getDept() {
  116. this.suredata = []
  117. this.deptList = []
  118. this.$api.to_http(this.src, "get").then(async (res) => {
  119. if (res.data.code != 0) {
  120. uni.$u.toast(res.data.msg)
  121. return
  122. }
  123. this.deptList = res.data.data
  124. await this.showData(this.deptList);
  125. this.$nextTick(() => {
  126. this.treeList = this.deptList[0].children;
  127. this.breadcrumbList.push(this.deptList[0]);
  128. this.show = true
  129. })
  130. })
  131. },
  132. details(e, i) {
  133. this.breadcrumbList.push(e);
  134. this.treeList = e.children;
  135. this.readNodes(this.deptList);
  136. },
  137. async showData(nodes = [], arr = []) {
  138. for (let item of nodes) {
  139. if (this.value) {
  140. this.value.split(',').forEach((x) => {
  141. if (x == item.id) {
  142. item.checked = true
  143. this.suredata.push(item)
  144. }
  145. })
  146. }
  147. if (!this.checkof && item.type == 'dept') {
  148. item.disabled = true
  149. }
  150. arr.push(item);
  151. if (item.children && item.children.length)
  152. this.showData(item.children, arr);
  153. }
  154. return arr;
  155. },
  156. readNodes(nodes = [], arr = []) {
  157. for (let item of nodes) {
  158. if (item.children) {
  159. item.children.forEach((items) => {
  160. items.pLabel = item.name;
  161. });
  162. }
  163. if (!this.checkof && item.type == 'dept') {
  164. item.disabled = true
  165. }
  166. arr.push(item);
  167. if (item.children && item.children.length)
  168. this.readNodes(item.children, arr);
  169. }
  170. return arr;
  171. },
  172. todept(e, i) {
  173. this.breadcrumbList.splice(i + 1);
  174. this.treeList = e.children;
  175. },
  176. change(e) {
  177. if (e.type == 'user') {
  178. e.checked = !e.checked;
  179. // 单选
  180. if (!this.checkof) {
  181. // 是否有数据
  182. if (this.suredata[0]) {
  183. this.suredata[0].checked = false;
  184. this.suredata = [];
  185. if (e.checked) {
  186. this.suredata.push(e);
  187. } else {
  188. if (!this.suredata.some((item) => e.id == item.id)) {}
  189. }
  190. } else {
  191. this.suredata.push(e);
  192. }
  193. } else {
  194. //多选
  195. if (e.checked) {
  196. this.suredata.push(e);
  197. } else {
  198. this.suredata.forEach((item, index) => {
  199. if (item.id == e.id) {
  200. this.suredata.splice(index, 1);
  201. }
  202. });
  203. }
  204. }
  205. } else {
  206. e.checked = false
  207. e.children.forEach((x) => {
  208. if (x.type == 'user') {
  209. x.checked = true
  210. this.suredata.push(x);
  211. }
  212. })
  213. }
  214. },
  215. }
  216. }
  217. </script>
  218. <style lang="less" scoped>
  219. .popup {
  220. background-color: #F5F5F5;
  221. font-size: 30rpx
  222. }
  223. .header {
  224. padding: 20rpx;
  225. text-align: center;
  226. background-color: #fff;
  227. border-bottom: 1px solid #F5F5F5;
  228. }
  229. .search {
  230. background-color: #fff;
  231. padding: 20rpx;
  232. }
  233. .breadcrumb {
  234. background-color: #fff;
  235. padding: 0 10rpx 10rpx 10rpx;
  236. font-size: 26rpx
  237. }
  238. .main {
  239. padding: 20rpx;
  240. margin-top: 20rpx;
  241. background-color: #fff;
  242. .tree {
  243. height: 600rpx;
  244. overflow: auto;
  245. .boxs {
  246. display: flex;
  247. >view {
  248. flex: 1
  249. }
  250. }
  251. }
  252. }
  253. .bottom {
  254. background-color: #fff;
  255. display: flex;
  256. justify-content: space-between;
  257. margin-top: 20rpx;
  258. padding: 10rpx;
  259. align-items: center;
  260. .sure {
  261. background: #3796F2;
  262. color: #fff;
  263. padding: 10rpx 20rpx;
  264. border-radius: 20rpx;
  265. }
  266. }
  267. .breadcrumb_c {
  268. color: #2561ef;
  269. }
  270. .breadcrumb_c:last-child {
  271. color: #000;
  272. }
  273. </style>