DepartList.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. <template xmlns:background-color="http://www.w3.org/1999/xhtml">
  2. <a-row :gutter="10">
  3. <a-col :md="12" :sm="24">
  4. <a-card :bordered="false">
  5. <!-- 按钮操作区域 -->
  6. <a-row style="margin-left: 14px">
  7. <a-button @click="handleAdd(1)" type="primary" v-has='"depart:add"'>添加部门</a-button>
  8. <a-button @click="handleAdd(2)" type="primary" v-has='"depart:subordinate"'>添加下级</a-button>
  9. <a-button type="primary" icon="download" @click="handleExportXls('部门信息')" v-has='"depart:export"'>导出</a-button>
  10. <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel" v-has='"depart:import"'>
  11. <a-button type="primary" icon="import">导入</a-button>
  12. </a-upload>
  13. <a-button title="删除多条数据" @click="batchDel" type="default" v-has='"depart:delete"'>批量删除</a-button>
  14. <!--<a-button @click="refresh" type="default" icon="reload" :loading="loading">刷新</a-button>-->
  15. </a-row>
  16. <div style="background: #fff;padding-left:16px;height: 100%; margin-top: 5px">
  17. <a-alert type="info" :showIcon="true">
  18. <div slot="message">
  19. 当前选择:<span v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</span>
  20. <a v-if="this.currSelected.title" style="margin-left: 10px" @click="onClearSelected">取消选择</a>
  21. </div>
  22. </a-alert>
  23. <a-input-search @search="onSearch" style="width:100%;margin-top: 10px" placeholder="请输入部门名称"/>
  24. <!-- 树-->
  25. <a-col :md="10" :sm="24">
  26. <template>
  27. <a-dropdown :trigger="[this.dropTrigger]" @visibleChange="dropStatus">
  28. <span style="user-select: none">
  29. <a-tree
  30. checkable
  31. multiple
  32. @select="onSelect"
  33. @check="onCheck"
  34. @rightClick="rightHandle"
  35. :selectedKeys="selectedKeys"
  36. :checkedKeys="checkedKeys"
  37. :treeData="departTree"
  38. :checkStrictly="checkStrictly"
  39. :expandedKeys="iExpandedKeys"
  40. :autoExpandParent="autoExpandParent"
  41. @expand="onExpand"/>
  42. </span>
  43. <!--新增右键点击事件,和增加添加和删除功能-->
  44. <a-menu slot="overlay">
  45. <a-menu-item @click="handleAdd(3)" key="1">添加</a-menu-item>
  46. <a-menu-item @click="handleDelete" key="2">删除</a-menu-item>
  47. <a-menu-item @click="closeDrop" key="3">取消</a-menu-item>
  48. </a-menu>
  49. </a-dropdown>
  50. </template>
  51. </a-col>
  52. </div>
  53. </a-card>
  54. <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
  55. <div class="drawer-bootom-button">
  56. <a-dropdown :trigger="['click']" placement="topCenter">
  57. <a-menu slot="overlay">
  58. <a-menu-item key="1" @click="switchCheckStrictly(1)">父子关联</a-menu-item>
  59. <a-menu-item key="2" @click="switchCheckStrictly(2)">取消关联</a-menu-item>
  60. <a-menu-item key="3" @click="checkALL">全部勾选</a-menu-item>
  61. <a-menu-item key="4" @click="cancelCheckALL">取消全选</a-menu-item>
  62. <a-menu-item key="5" @click="expandAll">展开所有</a-menu-item>
  63. <a-menu-item key="6" @click="closeAll">合并所有</a-menu-item>
  64. </a-menu>
  65. <a-button>
  66. 树操作 <a-icon type="up" />
  67. </a-button>
  68. </a-dropdown>
  69. </div>
  70. <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
  71. </a-col>
  72. <a-col :md="12" :sm="24">
  73. <a-tabs defaultActiveKey="1">
  74. <a-tab-pane tab="基本信息" key="1" >
  75. <a-card :bordered="false" v-if="selectedKeys.length>0">
  76. <a-form :form="form">
  77. <a-form-item
  78. :labelCol="labelCol"
  79. :wrapperCol="wrapperCol"
  80. label="机构名称">
  81. <a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/>
  82. </a-form-item>
  83. <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
  84. <a-tree-select
  85. style="width:100%"
  86. :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
  87. :treeData="treeData"
  88. v-model="model.parentId"
  89. placeholder="无">
  90. </a-tree-select>
  91. </a-form-item>
  92. <a-form-item
  93. :labelCol="labelCol"
  94. :wrapperCol="wrapperCol"
  95. label="机构编码">
  96. <a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/>
  97. </a-form-item>
  98. <a-form-item
  99. :labelCol="labelCol"
  100. :wrapperCol="wrapperCol"
  101. label="机构类型">
  102. <template v-if="orgCategoryDisabled">
  103. <a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
  104. <a-radio value="1">
  105. 公司
  106. </a-radio>
  107. </a-radio-group>
  108. </template>
  109. <template v-else>
  110. <a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
  111. <a-radio value="2">
  112. 部门
  113. </a-radio>
  114. <a-radio value="3">
  115. 岗位
  116. </a-radio>
  117. </a-radio-group>
  118. </template>
  119. </a-form-item>
  120. <a-form-item
  121. :labelCol="labelCol"
  122. :wrapperCol="wrapperCol"
  123. label="排序">
  124. <a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/>
  125. </a-form-item>
  126. <a-form-item
  127. :labelCol="labelCol"
  128. :wrapperCol="wrapperCol"
  129. label="手机号">
  130. <a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/>
  131. </a-form-item>
  132. <a-form-item
  133. :labelCol="labelCol"
  134. :wrapperCol="wrapperCol"
  135. label="地址">
  136. <a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/>
  137. </a-form-item>
  138. <a-form-item
  139. :labelCol="labelCol"
  140. :wrapperCol="wrapperCol"
  141. label="备注">
  142. <a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/>
  143. </a-form-item>
  144. </a-form>
  145. <div class="anty-form-btn">
  146. <a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync">重置</a-button>
  147. <a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form">保存</a-button>
  148. </div>
  149. </a-card>
  150. <a-card v-else >
  151. <a-empty>
  152. <span slot="description"> 请先选择一个部门! </span>
  153. </a-empty>
  154. </a-card>
  155. </a-tab-pane>
  156. <!-- <a-tab-pane tab="部门权限" key="2" forceRender>
  157. <depart-auth-modal ref="departAuth"/>
  158. </a-tab-pane> -->
  159. </a-tabs>
  160. </a-col>
  161. <depart-modal ref="departModal" @ok="loadTree"></depart-modal>
  162. </a-row>
  163. </template>
  164. <script>
  165. import DepartModal from './modules/DepartModal'
  166. import pick from 'lodash.pick'
  167. import {queryDepartTreeList, searchByKeywords, deleteByDepartId} from '@/api/api'
  168. import {httpAction, deleteAction} from '@/api/manage'
  169. import {JeecgListMixin} from '@/mixins/JeecgListMixin'
  170. import DepartAuthModal from './modules/DepartAuthModal'
  171. // 表头
  172. const columns = [
  173. {
  174. title: '机构名称',
  175. dataIndex: 'departName'
  176. },
  177. {
  178. title: '机构类型',
  179. align: 'center',
  180. dataIndex: 'orgType'
  181. },
  182. {
  183. title: '机构编码',
  184. dataIndex: 'orgCode',
  185. },
  186. {
  187. title: '手机号',
  188. dataIndex: 'mobile'
  189. },
  190. {
  191. title: '传真',
  192. dataIndex: 'fax'
  193. },
  194. {
  195. title: '地址',
  196. dataIndex: 'address'
  197. },
  198. {
  199. title: '排序',
  200. align: 'center',
  201. dataIndex: 'departOrder'
  202. },
  203. {
  204. title: '操作',
  205. align: 'center',
  206. dataIndex: 'action',
  207. scopedSlots: {customRender: 'action'}
  208. }
  209. ]
  210. export default {
  211. name: 'DepartList',
  212. mixins: [JeecgListMixin],
  213. components: {
  214. DepartAuthModal,
  215. DepartModal
  216. },
  217. data() {
  218. return {
  219. iExpandedKeys: [],
  220. loading: false,
  221. autoExpandParent: true,
  222. currFlowId: '',
  223. currFlowName: '',
  224. disable: true,
  225. treeData: [],
  226. visible: false,
  227. departTree: [],
  228. rightClickSelectedKey: '',
  229. rightClickSelectedOrgCode: '',
  230. hiding: true,
  231. model: {},
  232. dropTrigger: '',
  233. depart: {},
  234. columns: columns,
  235. disableSubmit: false,
  236. checkedKeys: [],
  237. selectedKeys: [],
  238. autoIncr: 1,
  239. currSelected: {},
  240. allTreeKeys:[],
  241. checkStrictly: true,
  242. form: this.$form.createForm(this),
  243. labelCol: {
  244. xs: {span: 24},
  245. sm: {span: 5}
  246. },
  247. wrapperCol: {
  248. xs: {span: 24},
  249. sm: {span: 16}
  250. },
  251. graphDatasource: {
  252. nodes: [],
  253. edges: []
  254. },
  255. validatorRules: {
  256. departName: {rules: [{required: true, message: '请输入机构/部门名称!'}]},
  257. orgCode: {rules: [{required: true, message: '请输入机构编码!'}]},
  258. orgCategory: {rules: [{required: true, message: '请输入机构类型!'}]},
  259. mobile: {rules: [{validator: this.validateMobile}]}
  260. },
  261. url: {
  262. delete: '/sys/sysDepart/delete',
  263. edit: '/sys/sysDepart/edit',
  264. deleteBatch: '/sys/sysDepart/deleteBatch',
  265. exportXlsUrl: "sys/sysDepart/exportXls",
  266. importExcelUrl: "sys/sysDepart/importExcel",
  267. },
  268. orgCategoryDisabled:false,
  269. }
  270. },
  271. computed: {
  272. importExcelUrl: function () {
  273. return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
  274. }
  275. },
  276. methods: {
  277. loadData() {
  278. this.refresh();
  279. },
  280. loadTree() {
  281. var that = this
  282. that.treeData = []
  283. that.departTree = []
  284. queryDepartTreeList().then((res) => {
  285. if (res.success) {
  286. //部门全选后,再添加部门,选中数量增多
  287. this.allTreeKeys = [];
  288. for (let i = 0; i < res.result.length; i++) {
  289. let temp = res.result[i]
  290. that.treeData.push(temp)
  291. that.departTree.push(temp)
  292. that.setThisExpandedKeys(temp)
  293. that.getAllKeys(temp);
  294. // console.log(temp.id)
  295. }
  296. this.loading = false
  297. }
  298. })
  299. },
  300. setThisExpandedKeys(node) {
  301. if (node.children && node.children.length > 0) {
  302. this.iExpandedKeys.push(node.key)
  303. for (let a = 0; a < node.children.length; a++) {
  304. this.setThisExpandedKeys(node.children[a])
  305. }
  306. }
  307. },
  308. refresh() {
  309. this.loading = true
  310. this.loadTree()
  311. },
  312. // 右键操作方法
  313. rightHandle(node) {
  314. this.dropTrigger = 'contextmenu'
  315. console.log(node.node.eventKey)
  316. this.rightClickSelectedKey = node.node.eventKey
  317. this.rightClickSelectedOrgCode = node.node.dataRef.orgCode
  318. },
  319. onExpand(expandedKeys) {
  320. console.log('onExpand', expandedKeys)
  321. // if not set autoExpandParent to false, if children expanded, parent can not collapse.
  322. // or, you can remove all expanded children keys.
  323. this.iExpandedKeys = expandedKeys
  324. this.autoExpandParent = false
  325. },
  326. backFlowList() {
  327. this.$router.back(-1)
  328. },
  329. // 右键点击下拉框改变事件
  330. dropStatus(visible) {
  331. if (visible == false) {
  332. this.dropTrigger = ''
  333. }
  334. },
  335. // 右键店家下拉关闭下拉框
  336. closeDrop() {
  337. this.dropTrigger = ''
  338. },
  339. addRootNode() {
  340. this.$refs.nodeModal.add(this.currFlowId, '')
  341. },
  342. batchDel: function () {
  343. console.log(this.checkedKeys)
  344. if (this.checkedKeys.length <= 0) {
  345. this.$message.warning('请选择一条记录!')
  346. } else {
  347. var ids = ''
  348. for (var a = 0; a < this.checkedKeys.length; a++) {
  349. ids += this.checkedKeys[a] + ','
  350. }
  351. var that = this
  352. this.$confirm({
  353. title: '确认删除',
  354. content: '确定要删除所选中的 ' + this.checkedKeys.length + ' 条数据,以及子节点数据吗?',
  355. onOk: function () {
  356. deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
  357. if (res.success) {
  358. that.$message.success(res.message)
  359. that.loadTree()
  360. that.onClearSelected()
  361. } else {
  362. that.$message.warning(res.message)
  363. }
  364. })
  365. }
  366. })
  367. }
  368. },
  369. onSearch(value) {
  370. let that = this
  371. if (value) {
  372. searchByKeywords({keyWord: value}).then((res) => {
  373. if (res.success) {
  374. that.departTree = []
  375. for (let i = 0; i < res.result.length; i++) {
  376. let temp = res.result[i]
  377. that.departTree.push(temp)
  378. }
  379. } else {
  380. that.$message.warning(res.message)
  381. }
  382. })
  383. } else {
  384. that.loadTree()
  385. }
  386. },
  387. nodeModalOk() {
  388. this.loadTree()
  389. },
  390. nodeModalClose() {
  391. },
  392. hide() {
  393. console.log(111)
  394. this.visible = false
  395. },
  396. onCheck(checkedKeys, info) {
  397. console.log('onCheck', checkedKeys, info)
  398. this.hiding = false
  399. //this.checkedKeys = checkedKeys.checked
  400. // <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
  401. if(this.checkStrictly){
  402. this.checkedKeys = checkedKeys.checked;
  403. }else{
  404. this.checkedKeys = checkedKeys
  405. }
  406. // <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
  407. },
  408. onSelect(selectedKeys, e) {
  409. console.log('selected', selectedKeys, e)
  410. this.hiding = false
  411. let record = e.node.dataRef
  412. console.log('onSelect-record', record)
  413. this.currSelected = Object.assign({}, record)
  414. this.model = this.currSelected
  415. this.selectedKeys = [record.key]
  416. this.model.parentId = record.parentId
  417. this.setValuesToForm(record)
  418. this.$refs.departAuth.show(record.id);
  419. },
  420. // 触发onSelect事件时,为部门树右侧的form表单赋值
  421. setValuesToForm(record) {
  422. if(record.orgCategory == '1'){
  423. this.orgCategoryDisabled = true;
  424. }else{
  425. this.orgCategoryDisabled = false;
  426. }
  427. this.$nextTick(() => {
  428. this.form.getFieldDecorator('fax', {initialValue: ''})
  429. this.form.setFieldsValue(pick(record, 'departName','orgCategory', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'))
  430. })
  431. },
  432. getCurrSelectedTitle() {
  433. return !this.currSelected.title ? '' : this.currSelected.title
  434. },
  435. onClearSelected() {
  436. this.hiding = true
  437. this.checkedKeys = []
  438. this.currSelected = {}
  439. this.form.resetFields()
  440. this.selectedKeys = []
  441. this.$refs.departAuth.departId = ''
  442. },
  443. handleNodeTypeChange(val) {
  444. this.currSelected.nodeType = val
  445. },
  446. notifyTriggerTypeChange(value) {
  447. this.currSelected.notifyTriggerType = value
  448. },
  449. receiptTriggerTypeChange(value) {
  450. this.currSelected.receiptTriggerType = value
  451. },
  452. submitCurrForm() {
  453. this.form.validateFields((err, values) => {
  454. if (!err) {
  455. if (!this.currSelected.id) {
  456. this.$message.warning('请点击选择要修改部门!')
  457. return
  458. }
  459. let formData = Object.assign(this.currSelected, values)
  460. console.log('Received values of form: ', formData)
  461. httpAction(this.url.edit, formData, 'put').then((res) => {
  462. if (res.success) {
  463. this.$message.success('保存成功!')
  464. this.loadTree()
  465. } else {
  466. this.$message.error(res.message)
  467. }
  468. })
  469. }
  470. })
  471. },
  472. emptyCurrForm() {
  473. this.form.resetFields()
  474. },
  475. nodeSettingFormSubmit() {
  476. this.form.validateFields((err, values) => {
  477. if (!err) {
  478. console.log('Received values of form: ', values)
  479. }
  480. })
  481. },
  482. openSelect() {
  483. this.$refs.sysDirectiveModal.show()
  484. },
  485. handleAdd(num) {
  486. if (num == 1) {
  487. this.$refs.departModal.add()
  488. this.$refs.departModal.title = '新增'
  489. } else if (num == 2) {
  490. let key = this.currSelected.key
  491. if (!key) {
  492. this.$message.warning('请先点击选中上级部门!')
  493. return false
  494. }
  495. this.$refs.departModal.add(this.selectedKeys)
  496. this.$refs.departModal.title = '新增'
  497. } else {
  498. this.$refs.departModal.add(this.rightClickSelectedKey)
  499. this.$refs.departModal.title = '新增'
  500. }
  501. },
  502. handleDelete() {
  503. var that = this
  504. this.$confirm({
  505. title: '确认删除',
  506. content: '确定要删除此部门以及子节点数据吗?',
  507. onOk: function () {
  508. deleteByDepartId({id: that.rightClickSelectedKey}).then((resp) => {
  509. if (resp.success) {
  510. //删除成功后,去除已选中中的数据
  511. that.checkedKeys.splice(that.checkedKeys.findIndex(key => key === that.rightClickSelectedKey), 1);
  512. that.$message.success('删除成功!')
  513. that.loadTree()
  514. //删除后同步清空右侧基本信息内容
  515. let orgCode=that.form.getFieldValue("orgCode");
  516. if(orgCode && orgCode === that.rightClickSelectedOrgCode){
  517. that.onClearSelected()
  518. }
  519. } else {
  520. that.$message.warning('删除失败!')
  521. }
  522. })
  523. }
  524. })
  525. },
  526. selectDirectiveOk(record) {
  527. console.log('选中指令数据', record)
  528. this.nodeSettingForm.setFieldsValue({directiveCode: record.directiveCode})
  529. this.currSelected.sysCode = record.sysCode
  530. },
  531. getFlowGraphData(node) {
  532. this.graphDatasource.nodes.push({
  533. id: node.id,
  534. text: node.flowNodeName
  535. })
  536. if (node.children.length > 0) {
  537. for (let a = 0; a < node.children.length; a++) {
  538. let temp = node.children[a]
  539. this.graphDatasource.edges.push({
  540. source: node.id,
  541. target: temp.id
  542. })
  543. this.getFlowGraphData(temp)
  544. }
  545. }
  546. },
  547. // <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
  548. expandAll () {
  549. this.iExpandedKeys = this.allTreeKeys
  550. },
  551. closeAll () {
  552. this.iExpandedKeys = []
  553. },
  554. checkALL () {
  555. this.checkStriccheckStrictlytly = false
  556. this.checkedKeys = this.allTreeKeys
  557. },
  558. cancelCheckALL () {
  559. //this.checkedKeys = this.defaultCheckedKeys
  560. this.checkedKeys = []
  561. },
  562. switchCheckStrictly (v) {
  563. if(v==1){
  564. this.checkStrictly = false
  565. }else if(v==2){
  566. this.checkStrictly = true
  567. }
  568. },
  569. getAllKeys(node) {
  570. // console.log('node',node);
  571. this.allTreeKeys.push(node.key)
  572. if (node.children && node.children.length > 0) {
  573. for (let a = 0; a < node.children.length; a++) {
  574. this.getAllKeys(node.children[a])
  575. }
  576. }
  577. }
  578. // <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
  579. },
  580. created() {
  581. this.currFlowId = this.$route.params.id
  582. this.currFlowName = this.$route.params.name
  583. // this.loadTree()
  584. },
  585. }
  586. </script>
  587. <style scoped>
  588. .ant-card-body .table-operator {
  589. margin: 15px;
  590. }
  591. .anty-form-btn {
  592. width: 100%;
  593. text-align: center;
  594. }
  595. .anty-form-btn button {
  596. margin: 0 5px;
  597. }
  598. .anty-node-layout .ant-layout-header {
  599. padding-right: 0
  600. }
  601. .header {
  602. padding: 0 8px;
  603. }
  604. .header button {
  605. margin: 0 3px
  606. }
  607. .ant-modal-cust-warp {
  608. height: 100%
  609. }
  610. .ant-modal-cust-warp .ant-modal-body {
  611. height: calc(100% - 110px) !important;
  612. overflow-y: auto
  613. }
  614. .ant-modal-cust-warp .ant-modal-content {
  615. height: 90% !important;
  616. overflow-y: hidden
  617. }
  618. #app .desktop {
  619. height: auto !important;
  620. }
  621. /** Button按钮间距 */
  622. .ant-btn {
  623. margin-left: 3px
  624. }
  625. .drawer-bootom-button {
  626. /*position: absolute;*/
  627. bottom: 0;
  628. width: 100%;
  629. border-top: 1px solid #e8e8e8;
  630. padding: 10px 16px;
  631. text-align: left;
  632. left: 0;
  633. background: #fff;
  634. border-radius: 0 0 2px 2px;
  635. }
  636. </style>