00fa05a3b51121ac09349e37935b5365cdb270a2.svn-base 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <template>
  2. <j-modal
  3. title="选择部门"
  4. :width="modalWidth"
  5. :visible="visible"
  6. :confirmLoading="confirmLoading"
  7. @ok="handleSubmit"
  8. @cancel="handleCancel"
  9. @update:fullscreen="isFullscreen"
  10. wrapClassName="j-depart-select-modal"
  11. switchFullscreen
  12. cancelText="关闭">
  13. <a-spin tip="Loading..." :spinning="false">
  14. <a-input-search style="margin-bottom: 1px" placeholder="请输入部门名称按回车进行搜索" @search="onSearch" />
  15. <a-tree
  16. checkable
  17. :class="treeScreenClass"
  18. :treeData="treeData"
  19. :checkStrictly="checkStrictly"
  20. @check="onCheck"
  21. @select="onSelect"
  22. @expand="onExpand"
  23. :autoExpandParent="autoExpandParent"
  24. :expandedKeys="expandedKeys"
  25. :checkedKeys="checkedKeys">
  26. <template slot="title" slot-scope="{title}">
  27. <span v-if="title.indexOf(searchValue) > -1">
  28. {{title.substr(0, title.indexOf(searchValue))}}
  29. <span style="color: #f50">{{searchValue}}</span>
  30. {{title.substr(title.indexOf(searchValue) + searchValue.length)}}
  31. </span>
  32. <span v-else>{{title}}</span>
  33. </template>
  34. </a-tree>
  35. </a-spin>
  36. <!--底部父子关联操作和确认取消按钮-->
  37. <template slot="footer" v-if="treeOpera && multi">
  38. <div class="drawer-bootom-button">
  39. <a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
  40. <a-menu slot="overlay">
  41. <a-menu-item key="1" @click="switchCheckStrictly(1)">父子关联</a-menu-item>
  42. <a-menu-item key="2" @click="switchCheckStrictly(2)">取消关联</a-menu-item>
  43. </a-menu>
  44. <a-button>
  45. 树操作 <a-icon type="up" />
  46. </a-button>
  47. </a-dropdown>
  48. <a-button @click="handleCancel" type="primary" style="margin-right: 0.8rem">关闭</a-button>
  49. <a-button @click="handleSubmit" type="primary" >确认</a-button>
  50. </div>
  51. </template>
  52. </j-modal>
  53. </template>
  54. <script>
  55. import { queryDepartTreeList } from '@/api/api'
  56. export default {
  57. name: 'JSelectDepartModal',
  58. props:['modalWidth','multi','rootOpened','departId', 'store', 'text','treeOpera'],
  59. data(){
  60. return {
  61. visible:false,
  62. confirmLoading:false,
  63. treeData:[],
  64. autoExpandParent:true,
  65. expandedKeys:[],
  66. dataList:[],
  67. checkedKeys:[],
  68. checkedRows:[],
  69. searchValue:"",
  70. checkStrictly: true,
  71. fullscreen:false
  72. }
  73. },
  74. created(){
  75. this.loadDepart();
  76. },
  77. watch:{
  78. departId(){
  79. this.initDepartComponent()
  80. },
  81. visible: {
  82. handler() {
  83. this.initDepartComponent(true)
  84. }
  85. }
  86. },
  87. computed:{
  88. treeScreenClass() {
  89. return {
  90. 'my-dept-select-tree': true,
  91. 'fullscreen': this.fullscreen,
  92. }
  93. },
  94. },
  95. methods:{
  96. show(){
  97. this.visible=true
  98. this.checkedRows=[]
  99. this.checkedKeys=[]
  100. },
  101. loadDepart(){
  102. // 这个方法是找到所有的部门信息
  103. queryDepartTreeList().then(res=>{
  104. if(res.success){
  105. let arr = [...res.result]
  106. this.reWriterWithSlot(arr)
  107. this.treeData = arr
  108. this.initDepartComponent()
  109. if(this.rootOpened){
  110. this.initExpandedKeys(res.result)
  111. }
  112. }
  113. })
  114. },
  115. initDepartComponent(flag){
  116. let arr = []
  117. //该方法两个地方用 1.visible改变事件重新设置选中项 2.组件编辑页面回显
  118. let fieldName = flag==true?'key':this.text
  119. if(this.departId){
  120. let arr2 = this.departId.split(',')
  121. for(let item of this.dataList){
  122. if(arr2.indexOf(item[this.store])>=0){
  123. arr.push(item[fieldName])
  124. }
  125. }
  126. }
  127. if(flag==true){
  128. this.checkedKeys = [...arr]
  129. }else{
  130. this.$emit("initComp", arr.join(','))
  131. }
  132. },
  133. reWriterWithSlot(arr){
  134. for(let item of arr){
  135. if(item.children && item.children.length>0){
  136. this.reWriterWithSlot(item.children)
  137. let temp = Object.assign({},item)
  138. temp.children = {}
  139. this.dataList.push(temp)
  140. }else{
  141. this.dataList.push(item)
  142. item.scopedSlots={ title: 'title' }
  143. }
  144. }
  145. },
  146. initExpandedKeys(arr){
  147. if(arr && arr.length>0){
  148. let keys = []
  149. for(let item of arr){
  150. if(item.children && item.children.length>0){
  151. keys.push(item.id)
  152. }
  153. }
  154. this.expandedKeys=[...keys]
  155. //全部keys
  156. //this.allTreeKeys = [...keys]
  157. }else{
  158. this.expandedKeys=[]
  159. //this.allTreeKeys = []
  160. }
  161. },
  162. onCheck (checkedKeys,info) {
  163. if(!this.multi){
  164. let arr = checkedKeys.checked.filter(item => this.checkedKeys.indexOf(item) < 0)
  165. this.checkedKeys = [...arr]
  166. this.checkedRows = (this.checkedKeys.length === 0) ? [] : [info.node.dataRef]
  167. }else{
  168. if(this.checkStrictly){
  169. this.checkedKeys = checkedKeys.checked
  170. }else{
  171. this.checkedKeys = checkedKeys
  172. }
  173. this.checkedRows = this.getCheckedRows(this.checkedKeys)
  174. }
  175. },
  176. onSelect(selectedKeys,info) {
  177. //取消关联的情况下才走onSelect的逻辑
  178. if(this.checkStrictly){
  179. let keys = []
  180. keys.push(selectedKeys[0])
  181. if(!this.checkedKeys || this.checkedKeys.length===0 || !this.multi){
  182. this.checkedKeys = [...keys]
  183. this.checkedRows=[info.node.dataRef]
  184. }else{
  185. let currKey = info.node.dataRef.key
  186. if(this.checkedKeys.indexOf(currKey)>=0){
  187. this.checkedKeys = this.checkedKeys.filter(item=> item !==currKey)
  188. }else{
  189. this.checkedKeys.push(...keys)
  190. }
  191. }
  192. this.checkedRows = this.getCheckedRows(this.checkedKeys)
  193. }
  194. },
  195. onExpand (expandedKeys) {
  196. this.expandedKeys = expandedKeys
  197. this.autoExpandParent = false
  198. },
  199. handleSubmit(){
  200. if(!this.checkedKeys || this.checkedKeys.length==0){
  201. this.$emit("ok",'')
  202. }else{
  203. let checkRow = this.getCheckedRows(this.checkedKeys)
  204. let keyStr = this.checkedKeys.join(",")
  205. this.$emit("ok", checkRow, keyStr)
  206. }
  207. this.handleClear()
  208. },
  209. handleCancel(){
  210. this.handleClear()
  211. },
  212. handleClear(){
  213. this.visible=false
  214. this.checkedKeys=[]
  215. },
  216. getParentKey(currKey,treeData){
  217. let parentKey
  218. for (let i = 0; i < treeData.length; i++) {
  219. const node = treeData[i]
  220. if (node.children) {
  221. if (node.children.some(item => item.key === currKey)) {
  222. parentKey = node.key
  223. } else if (this.getParentKey(currKey, node.children)) {
  224. parentKey = this.getParentKey(currKey, node.children)
  225. }
  226. }
  227. }
  228. return parentKey
  229. },
  230. onSearch(value){
  231. const expandedKeys = this.dataList.map((item) => {
  232. if (item.title.indexOf(value) > -1) {
  233. return this.getParentKey(item.key,this.treeData)
  234. }
  235. return null
  236. }).filter((item, i, self) => item && self.indexOf(item) === i)
  237. Object.assign(this, {
  238. expandedKeys,
  239. searchValue: value,
  240. autoExpandParent: true,
  241. })
  242. },
  243. // 根据 checkedKeys 获取 rows
  244. getCheckedRows(checkedKeys) {
  245. const forChildren = (list, key) => {
  246. for (let item of list) {
  247. if (item.id === key) {
  248. return item
  249. }
  250. if (item.children instanceof Array) {
  251. let value = forChildren(item.children, key)
  252. if (value != null) {
  253. return value
  254. }
  255. }
  256. }
  257. return null
  258. }
  259. let rows = []
  260. for (let key of checkedKeys) {
  261. let row = forChildren(this.treeData, key)
  262. if (row != null) {
  263. rows.push(row)
  264. }
  265. }
  266. return rows
  267. },
  268. switchCheckStrictly (v) {
  269. if(v==1){
  270. this.checkStrictly = false
  271. }else if(v==2){
  272. this.checkStrictly = true
  273. }
  274. },
  275. isFullscreen(val){
  276. this.fullscreen=val
  277. }
  278. }
  279. }
  280. </script>
  281. <style lang="less" scoped>
  282. // 限制部门选择树高度,避免部门太多时点击确定不便
  283. .my-dept-select-tree{
  284. height:350px;
  285. &.fullscreen{
  286. height: calc(100vh - 250px);
  287. }
  288. overflow-y: scroll;
  289. }
  290. .drawer-bootom-button {
  291. position: absolute;
  292. bottom: 0;
  293. width: 100%;
  294. border-top: 1px solid #e8e8e8;
  295. padding: 10px 16px;
  296. text-align: right;
  297. left: 0;
  298. background: #fff;
  299. border-radius: 0 0 2px 2px;
  300. }
  301. </style>