Transfer.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <template>
  2. <div>
  3. <!-- 穿梭框 -->
  4. <div>
  5. <el-dialog v-model="transferModals" title="分享" width="40%" :close-on-click-modal="false">
  6. <div class="transBox">
  7. <div class="allBag">
  8. <div style="position: relative;">
  9. <el-input style="width: 220px;margin-left: 18px;margin-top:5px" v-model="allBag"
  10. placeholder="搜索"></el-input>
  11. </div>
  12. <div class="allLog">
  13. <el-tree :filter-node-method="filterNode" v-if="have" ref="treeRef" :data="allTreeData"
  14. :props="allTreeProps" show-checkbox node-key="id" :default-expanded-keys="openTree"
  15. @check-change="allTreeChange" :default-checked-keys="backScreen" :check-strictly="false" />
  16. <span v-else>暂无数据</span>
  17. </div>
  18. </div>
  19. <div class="needBag">
  20. <div style="border-bottom: 1px solid gray;" class="needBag_top">
  21. <span>已选择{{ chooseTagData.length }}人</span>
  22. <span style="color: red;font-size: 14px;float: right;cursor: pointer;"
  23. @click="cleanPeople">清空</span>
  24. </div>
  25. <div class="needLog">
  26. <el-scrollbar height="349px">
  27. <el-tag v-for="(item, index) in chooseTagData" :key="index" class="tagtag" :closable="true"
  28. @close="handleClose(item)">
  29. {{ item.userName ? item.userName : item.name }}
  30. </el-tag>
  31. </el-scrollbar>
  32. </div>
  33. </div>
  34. </div>
  35. <template #footer>
  36. <span class="dialog-footer">
  37. <el-button @click="backToFather">取消</el-button>
  38. <el-button type="primary" @click="sureShare">
  39. 确定
  40. </el-button>
  41. </span>
  42. </template>
  43. </el-dialog>
  44. </div>
  45. </div>
  46. </template>
  47. <script>
  48. import { ref, onMounted, toRef, watch, toRaw } from 'vue';
  49. import userTree from '../../../api/user/userTree';
  50. import fileShare from '../../../api/fileShare/fileShare';
  51. import fileCount from '../../../api/fileCount/fileCount'
  52. import { ElMessage } from 'element-plus'
  53. export default {
  54. props: {
  55. thanks: {
  56. type: Boolean,
  57. required: true
  58. },
  59. clickRowId: {
  60. type: Number,
  61. required: true
  62. },
  63. workOrEdit: {
  64. type: Number,
  65. required: true
  66. },
  67. isNewMenu: {
  68. type: Boolean,
  69. required: true
  70. },
  71. },
  72. setup(props, { emit }) {
  73. let { backToFather, sureBackFather } = toRefs(props)
  74. let result = props.thanks
  75. let dees = props.clickRowId
  76. let feeh = props.workOrEdit
  77. let isNewMenus = props.isNewMenu
  78. let transferModals = ref(false)
  79. let allTreeData = ref([])
  80. let allTreeProps = {
  81. label: 'label',
  82. children: 'children',
  83. disabled: false,
  84. id: "id"
  85. }
  86. let treeRef = ref(null)
  87. let openTree = ref([])
  88. let chooseTagData = ref([])
  89. let allBag = ref('')
  90. let needTagData = ref([])
  91. let backScreen = ref([])
  92. let lastPeople = ref(false)
  93. let allCancel = ref(false)
  94. let have = ref(true)
  95. function allTeam() {
  96. if (result) {
  97. transferModals.value = result
  98. }
  99. }
  100. // 分享穿梭框
  101. function allTreeChange(e) {
  102. // console.log('触发了change事件'+ 1++);
  103. const id = e.id;
  104. const label = e.label;
  105. const disabled = e.disabled;
  106. // 查找是否已经存在相同 userId 的数据的索引
  107. const existingIndex = chooseTagData.value.findIndex(item => item.userId === id);
  108. if (existingIndex !== -1) {
  109. // 如果已存在,删除该项
  110. chooseTagData.value.splice(existingIndex, 1);
  111. } else {
  112. // 选择操作,将数据添加到 needTagData 中
  113. chooseTagData.value.push({ userId: id, userName: label, disabled: disabled });
  114. }
  115. if (chooseTagData.value.length === 1) {
  116. lastPeople.value = true
  117. } else {
  118. lastPeople.value = false
  119. }
  120. chooseTagData.value = chooseTagData.value.filter(item => !item.disabled)
  121. // console.log('chooseTagData初始数组',chooseTagData.value);
  122. }
  123. // 确认分享
  124. function sureShare() {
  125. if (feeh === 1) {
  126. if (chooseTagData.value.length === 0) {
  127. ElMessage({
  128. type: "error",
  129. message: "你还未选择人员!"
  130. })
  131. } else {
  132. console.log(chooseTagData.value, 'value');
  133. let arr = []
  134. arr = chooseTagData.value.map(item => {
  135. return item.userId
  136. })
  137. fileShare.addSharePeople(dees, arr).then(res => {
  138. if (res.code === 200) {
  139. ElMessage({
  140. message: "分享成功",
  141. type: "success"
  142. })
  143. transferModals.value = false
  144. emit("getCback", transferModals.value)
  145. }
  146. })
  147. }
  148. } else {
  149. if (chooseTagData.value.length === 0) {
  150. ElMessage({
  151. type: "error",
  152. message: "你还未选择人员!"
  153. })
  154. } else {
  155. let arr = []
  156. arr = chooseTagData.value.map(item => {
  157. return item.userId
  158. })
  159. fileCount.addActor(dees, arr).then(res => {
  160. if (res.code === 200) {
  161. ElMessage({
  162. message: "提醒人员成功",
  163. type: "success"
  164. })
  165. transferModals.value = false
  166. emit("getCback", transferModals.value)
  167. }
  168. })
  169. }
  170. }
  171. }
  172. // 获取用户树
  173. function getAllUser() {
  174. userTree.getUserTree({}).then(res => {
  175. allTreeData.value = [res]
  176. userTree.getUserTree({}).then(res => {
  177. allTreeData.value = [res];
  178. // 递归函数来获取所有节点的 id
  179. function getAllNodeIds(nodes) {
  180. nodes.forEach(node => {
  181. openTree.value.push(node.id);
  182. if (node.children && node.children.length > 0) {
  183. getAllNodeIds(node.children);
  184. }
  185. });
  186. }
  187. // 调用递归函数获取所有节点的 id
  188. getAllNodeIds(allTreeData.value);
  189. });
  190. })
  191. if (feeh === 1) {
  192. fileShare.getSharePeople(dees).then(res => {
  193. // 去除数组内部的重复元素
  194. const uniqueRes = Array.from(new Set(res.map(item => item.userName))).map(id => res.find(item => item.userName === id));
  195. // 现在的 uniqueRes 数组不包含重复元素
  196. chooseTagData.value = uniqueRes;
  197. backScreen.value = chooseTagData.value.map(item => {
  198. return item.userId
  199. })
  200. })
  201. }
  202. if (feeh === 0) {
  203. fileCount.getActor(dees).then(res => {
  204. chooseTagData.value = res;
  205. backScreen.value = chooseTagData.value.map(item => {
  206. return item.userId
  207. })
  208. })
  209. } else if (!isNewMenus) {
  210. fileCount.getActor(dees).then(res => {
  211. chooseTagData.value = res
  212. })
  213. }
  214. }
  215. function cleanPeople() {
  216. treeRef.value.setCheckedKeys([]);
  217. chooseTagData.value = [];
  218. setTimeout(() => {
  219. antherClean()
  220. })
  221. }
  222. function antherClean() {
  223. treeRef.value.setCheckedKeys([]);
  224. chooseTagData.value = [];
  225. }
  226. function searchInTreeData(treeData, searchValue) {
  227. const foundItems = [];
  228. function traverseTree(node) {
  229. if (node.label.includes(searchValue)) {
  230. foundItems.push(node);
  231. }
  232. if (node.children) {
  233. node.children.forEach(childNode => traverseTree(childNode));
  234. }
  235. }
  236. treeData.forEach(node => traverseTree(node));
  237. return foundItems;
  238. }
  239. watch(()=>allBag.value,(val)=>{
  240. treeRef.value?.filter(val)
  241. })
  242. function filterNode(value, data) {
  243. if (!value) return true
  244. return data.label.includes(value)
  245. }
  246. function getBack() {
  247. transferModals.value = false
  248. emit("getCback", transferModals.value)
  249. }
  250. function handleClose(tag) {
  251. const arr = toRaw(chooseTagData.value)
  252. console.log('arr',arr);
  253. chooseTagData.value.splice(chooseTagData.value.indexOf(tag), 1);
  254. let result = chooseTagData.value.map((item) => {
  255. return item.userId
  256. })
  257. treeRef.value.setCheckedKeys(result);
  258. setTimeout(() => {
  259. antherClose(tag)
  260. }, 10)
  261. }
  262. function antherClose(tag) {
  263. chooseTagData.value.splice(chooseTagData.value.indexOf(tag), 1);
  264. let result = chooseTagData.value.map((item) => {
  265. return item.userId
  266. })
  267. treeRef.value.setCheckedKeys(result);
  268. }
  269. onMounted(() => {
  270. allTeam()
  271. getAllUser()
  272. })
  273. return {
  274. transferModals,
  275. allTreeData,
  276. allTreeProps,
  277. openTree,
  278. chooseTagData,
  279. allTreeChange,
  280. sureShare,
  281. allBag,
  282. getAllUser,
  283. result,
  284. allTeam,
  285. dees,
  286. needTagData,
  287. handleClose,
  288. backScreen,
  289. lastPeople,
  290. feeh,
  291. backToFather: getBack,
  292. cleanPeople,
  293. treeRef,
  294. have,
  295. filterNode,
  296. }
  297. }
  298. }
  299. </script>
  300. <style scoped>
  301. .transBox {
  302. width: 550px;
  303. height: 400px;
  304. margin: 0 auto;
  305. display: flex;
  306. justify-content: space-around;
  307. align-items: center;
  308. /* border: 1px solid black; */
  309. }
  310. .tagtag {
  311. display: flex;
  312. justify-content: space-between;
  313. align-items: center;
  314. text-align: start;
  315. width: 230px;
  316. margin: 0 auto;
  317. }
  318. .allBag {
  319. width: 255px;
  320. height: 400px;
  321. border: 1px solid green;
  322. overflow-y: auto;
  323. }
  324. .needBag {
  325. width: 255px;
  326. height: 400px;
  327. border: 1px solid green;
  328. overflow-y: auto;
  329. }
  330. .allLog {
  331. width: 245px;
  332. height: 330px;
  333. margin: 5px auto;
  334. /* border: 1px solid red; */
  335. overflow-y: auto;
  336. text-align: center;
  337. }
  338. .needBag_top {
  339. padding: 0 10px;
  340. height: 30px;
  341. display: flex;
  342. align-items: center;
  343. justify-content: space-between;
  344. }
  345. .needLog {
  346. height: 100%;
  347. overflow-y: auto;
  348. }
  349. :deep(.el-tag__content) {
  350. display: block;
  351. }
  352. :deep(.el-icon el-tag__close) {
  353. display: block;
  354. }
  355. :deep(.el-scrollbar__wrap .el-scrollbar__wrap--hidden-default) {
  356. height: 346px !important;
  357. }
  358. </style>