UserSelectDialog.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <template>
  2. <el-dialog
  3. v-model="dialogVisible"
  4. title="人员选择"
  5. :width="type == 1 ? 680 : 460"
  6. destroy-on-close
  7. append-to-body
  8. @closed="$emit('closed')"
  9. draggable
  10. >
  11. <template v-if="type == 1">
  12. <div class="user-select">
  13. <div class="user-select__left">
  14. <div class="user-select__search">
  15. <el-input
  16. v-model="searchForm.name"
  17. prefix-icon="search"
  18. placeholder="搜索成员"
  19. clearable
  20. >
  21. <template #append>
  22. <el-button
  23. icon="search"
  24. @click="search"
  25. ></el-button>
  26. </template>
  27. </el-input>
  28. </div>
  29. <div class="user-select__select">
  30. <div
  31. class="user-select__tree"
  32. v-loading="showGrouploading"
  33. >
  34. <el-scrollbar>
  35. <el-tree
  36. class="menu"
  37. ref="groupTree"
  38. :data="group"
  39. node-key="id"
  40. :props="{
  41. label: 'name',
  42. children: 'children',
  43. }"
  44. highlight-current
  45. :expand-on-click-node="false"
  46. :current-node-key="groupId"
  47. @node-click="groupClick"
  48. >
  49. <template #default="{ node, data }">
  50. <span
  51. class="custom-tree-node el-tree-node__label"
  52. >
  53. <span class="label">
  54. <el-icon
  55. :size="16"
  56. class="m-r-5"
  57. >
  58. <qiye
  59. v-if="data.type === '1'"
  60. :style="{
  61. color:
  62. $TOOL.data.get(
  63. 'IS_PRIMARY_TENANT'
  64. ) &&
  65. data.tenantDTO &&
  66. $utils.getTenantColorById(
  67. data
  68. .tenantDTO
  69. .id
  70. ),
  71. }"
  72. ></qiye>
  73. <bumen
  74. v-else
  75. :style="{
  76. color:
  77. $TOOL.data.get(
  78. 'IS_PRIMARY_TENANT'
  79. ) &&
  80. data.tenantDTO &&
  81. $utils.getTenantColorById(
  82. data
  83. .tenantDTO
  84. .id
  85. ),
  86. }"
  87. ></bumen>
  88. </el-icon>
  89. {{ node.label }}
  90. </span>
  91. </span>
  92. </template>
  93. </el-tree>
  94. </el-scrollbar>
  95. </div>
  96. <div
  97. class="user-select__user"
  98. v-loading="showUserloading"
  99. >
  100. <div class="user-select__user__list">
  101. <el-scrollbar ref="userScrollbar">
  102. <el-tree
  103. class="menu"
  104. ref="userTree"
  105. :data="user"
  106. node-key="id"
  107. highlight-current
  108. :props="{
  109. key: 'id',
  110. label: 'name',
  111. children: 'children',
  112. }"
  113. :default-checked-keys="selectedIds"
  114. :show-checkbox="limit > 1"
  115. check-on-click-node
  116. @check-change="userClick"
  117. ></el-tree>
  118. </el-scrollbar>
  119. </div>
  120. <footer>
  121. <el-pagination
  122. background
  123. layout="prev,next"
  124. small
  125. :total="total"
  126. :page-size="pageSize"
  127. v-model:currentPage="currentPage"
  128. @current-change="paginationChange"
  129. ></el-pagination>
  130. </footer>
  131. </div>
  132. </div>
  133. </div>
  134. <div class="user-select__toicon">
  135. <el-icon><arrow-right /></el-icon>
  136. </div>
  137. <div class="user-select__selected">
  138. <header>已选 ({{ selected.length }})</header>
  139. <ul>
  140. <el-scrollbar>
  141. <li
  142. v-for="(item, index) in selected"
  143. :key="item.id"
  144. >
  145. <span class="name">
  146. <el-avatar
  147. v-if="
  148. $TOOL.data.get('IS_PRIMARY_TENANT')
  149. "
  150. :size="30"
  151. :style="{
  152. background:
  153. $utils.getTenantColorById(
  154. item.tenantId
  155. ) + '!important',
  156. }"
  157. >{{
  158. item.name.substring(0, 1)
  159. }}</el-avatar
  160. >
  161. <el-avatar v-else>{{
  162. item.name.substring(0, 1)
  163. }}</el-avatar>
  164. <label>{{ item.name }}</label>
  165. </span>
  166. <span class="delete">
  167. <el-button
  168. text
  169. type="primary"
  170. icon="del-filled"
  171. circle
  172. size="small"
  173. @click="deleteSelected(index)"
  174. ></el-button>
  175. </span>
  176. </li>
  177. </el-scrollbar>
  178. </ul>
  179. </div>
  180. </div>
  181. </template>
  182. <template #footer>
  183. <el-button @click="resetSearch()" style="background-color: #F2F6FC" icon="el-icon-refresh-right">重置</el-button>
  184. <el-button @click="dialogVisible = false">取 消</el-button>
  185. <el-button type="primary" @click="save">确 认</el-button>
  186. </template>
  187. </el-dialog>
  188. </template>
  189. <script>
  190. import userService from "@/api/sys/userService";
  191. import officeService from "@/api/sys/officeService";
  192. export default {
  193. props: {
  194. tenantId: { type: String, default: null },
  195. limit: {
  196. type: Number,
  197. default: 999999,
  198. },
  199. },
  200. data() {
  201. return {
  202. searchForm: {
  203. loginName: "",
  204. companyDTO: {
  205. id: "",
  206. },
  207. officeDTO: {
  208. id: "",
  209. },
  210. name: "",
  211. },
  212. dialogVisible: false,
  213. showGrouploading: false,
  214. showUserloading: false,
  215. groupId: "",
  216. pageSize: 10,
  217. total: 0,
  218. currentPage: 1,
  219. group: [],
  220. user: [],
  221. role: [],
  222. type: 1,
  223. selected: [],
  224. value: [],
  225. };
  226. },
  227. computed: {
  228. selectedIds() {
  229. return this.selected.map((t) => t.id);
  230. },
  231. },
  232. methods: {
  233. //打开赋值
  234. async open(data) {
  235. console.log("进入open方法")
  236. this.value = data || [];
  237. this.selected = JSON.parse(JSON.stringify(data || []));
  238. this.dialogVisible = true;
  239. await this.getGroup();
  240. this.getUser();
  241. },
  242. //获取组织
  243. async getGroup() {
  244. console.log("进入getGroup方法")
  245. this.showGrouploading = true;
  246. // officeService.treeData().then((data) => {
  247. // this.officeTreeData = data
  248. // this.showGrouploading = false;
  249. // })
  250. var res = await officeService.treeData({ tenantId: this.tenantId });
  251. this.showGrouploading = false;
  252. // var allNode = { id: "", type: "1", name: "所有" };
  253. // res.unshift(allNode);
  254. this.group = res;
  255. this.searchForm.companyDTO.id = this.group[0].id;
  256. },
  257. //获取用户
  258. async getUser() {
  259. this.showUserloading = true;
  260. userService
  261. .list({
  262. current: this.currentPage,
  263. size: this.pageSize,
  264. ...this.searchForm,
  265. "tenantDTO.id": this.tenantId,
  266. })
  267. .then((data) => {
  268. this.user = data.records;
  269. this.total = data.total;
  270. // this.pageNo = data.current
  271. this.showUserloading = false;
  272. this.$refs.userScrollbar.setScrollTop(0);
  273. });
  274. },
  275. //组织点击
  276. groupClick(data) {
  277. if (data.type === "1") {
  278. this.searchForm.companyDTO.id = data.id;
  279. this.searchForm.officeDTO.id = "";
  280. } else {
  281. this.searchForm.companyDTO.id = "";
  282. this.searchForm.officeDTO.id = data.id;
  283. }
  284. this.currentPage = 1;
  285. this.groupId = data.id;
  286. this.getUser();
  287. },
  288. //用户点击
  289. userClick(data, checked) {
  290. if (checked) {
  291. if (this.limit === 1) {
  292. this.selected = [
  293. {
  294. id: data.id,
  295. name: data.name,
  296. tenantId: data.tenantDTO?.id,
  297. },
  298. ];
  299. } else {
  300. this.selected.push({
  301. id: data.id,
  302. name: data.name,
  303. tenantId: data.tenantDTO?.id,
  304. });
  305. }
  306. } else {
  307. this.selected = this.selected.filter(
  308. (item) => item.id != data.id
  309. );
  310. }
  311. },
  312. resetSearch () {
  313. this.getGroup()
  314. this.searchForm.companyDTO.id = ''
  315. this.searchForm.name = ''
  316. this.currentPage = 1;
  317. this.getUser();
  318. },
  319. //用户分页点击
  320. paginationChange() {
  321. this.getUser();
  322. },
  323. //用户搜索
  324. search() {
  325. // this.groupId = ''
  326. // this.$refs.groupTree.setCurrentKey(this.groupId)
  327. this.currentPage = 1;
  328. this.getUser();
  329. },
  330. //删除已选
  331. deleteSelected(index) {
  332. this.selected.splice(index, 1);
  333. console.log(this.selected);
  334. if (this.type == 1) {
  335. this.$refs.userTree.setCheckedKeys(this.selectedIds);
  336. } else if (this.type == 2) {
  337. this.$refs.groupTree.setCheckedKeys(this.selectedIds);
  338. }
  339. },
  340. //提交保存
  341. save() {
  342. this.value.splice(0, this.value.length);
  343. this.selected.map((item) => {
  344. this.value.push(item);
  345. });
  346. if (this.limit < this.value.length) {
  347. this.$message.error(`你最多只能选择${this.limit}个用户`);
  348. return;
  349. }
  350. this.$emit("doSubmit", this.value);
  351. console.log(this.value)
  352. this.dialogVisible = false;
  353. },
  354. },
  355. };
  356. </script>
  357. <style scoped>
  358. .user-select {
  359. display: flex;
  360. }
  361. .user-select__left {
  362. width: 400px;
  363. }
  364. .user-select__right {
  365. flex: 1;
  366. }
  367. .user-select__selected li .name .el-avatar {
  368. margin-right: 2px;
  369. height: 10;
  370. width: 25px;
  371. height: 25px;
  372. }
  373. .user-select__search {
  374. padding-bottom: 10px;
  375. }
  376. .user-select__select {
  377. display: flex;
  378. border: 1px solid var(--el-border-color-light);
  379. background: var(--el-color-white);
  380. }
  381. .user-select__tree {
  382. width: 200px;
  383. height: 300px;
  384. border-right: 1px solid var(--el-border-color-light);
  385. }
  386. .user-select__user {
  387. width: 200px;
  388. height: 300px;
  389. display: flex;
  390. flex-direction: column;
  391. }
  392. .user-select__user__list {
  393. flex: 1;
  394. overflow: auto;
  395. }
  396. .user-select__user footer {
  397. height: 36px;
  398. padding-top: 5px;
  399. border-top: 1px solid var(--el-border-color-light);
  400. }
  401. .user-select__toicon {
  402. display: flex;
  403. justify-content: center;
  404. align-items: center;
  405. margin: 0 10px;
  406. }
  407. .user-select__toicon i {
  408. display: flex;
  409. justify-content: center;
  410. align-items: center;
  411. background: #ccc;
  412. width: 20px;
  413. height: 20px;
  414. text-align: center;
  415. line-height: 20px;
  416. border-radius: 50%;
  417. color: #fff;
  418. }
  419. .user-select__selected {
  420. height: 345px;
  421. width: 200px;
  422. border: 1px solid var(--el-border-color-light);
  423. background: var(--el-color-white);
  424. }
  425. .user-select__selected header {
  426. height: 43px;
  427. line-height: 43px;
  428. border-bottom: 1px solid var(--el-border-color-light);
  429. padding: 0 15px;
  430. font-size: 16px;
  431. }
  432. .user-select__selected ul {
  433. height: 300px;
  434. overflow: auto;
  435. }
  436. .user-select__selected li {
  437. display: flex;
  438. align-items: center;
  439. justify-content: space-between;
  440. padding: 5px 5px 5px 15px;
  441. height: 38px;
  442. }
  443. .user-select__selected li .name {
  444. display: flex;
  445. align-items: center;
  446. }
  447. .user-select__selected li .name .el-avatar {
  448. margin-right: 10px;
  449. }
  450. .user-select__selected li .delete {
  451. display: none;
  452. }
  453. .user-select__selected li:hover {
  454. background: var(--el-color-primary-light-9);
  455. }
  456. .user-select__selected li:hover .delete {
  457. display: inline-block;
  458. }
  459. .user-select-role .user-select__left {
  460. width: 200px;
  461. }
  462. .user-select-role .user-select__tree {
  463. border: none;
  464. height: 343px;
  465. }
  466. </style>