DepartList.vue 20 KB

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