index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. <template>
  2. <el-container>
  3. <el-main class="page-main">
  4. <el-container>
  5. <el-header style="margin-bottom: 10px;">
  6. <query ref="searchForm" :form-config="query" @onSubmit="search" @onCreate="create" @onDeleteBatch="deleteBatch" />
  7. </el-header>
  8. <el-main>
  9. <sheet ref="qtable" :api="this.$api.sysRole.page" :columns="tableColumns" :data-query="dataQuery" :operates="operates" :float-type="'right'" :select-type="'selection'" :selection-data.sync="selectionData" />
  10. </el-main>
  11. </el-container>
  12. </el-main>
  13. <el-dialog :title="dialogStatus==='create'? $t('common.create'):$t('common.update')" :visible.sync="dialogVisible" width="60%" @close="dialogClose">
  14. <el-form ref="dataForm" :size="size" :rules="rules" :model="temp" label-width="85px">
  15. <el-form-item label="角色名:" prop="name">
  16. <el-input v-model="temp.name" :size="size" placeholder="请输入角色名" />
  17. </el-form-item>
  18. <el-form-item label="编码:" prop="code">
  19. <el-input v-model="temp.code" :size="size" placeholder="请输入编码" />
  20. </el-form-item>
  21. <el-form-item label="状态:" prop="status">
  22. <option-set :value.sync="temp.status" placeholder="请选择状态" code="sys_role_status" />
  23. </el-form-item>
  24. <el-form-item label="后台首页:" prop="admin_index">
  25. <el-input v-model="temp.admin_index" :size="size" placeholder="请输入后台首页" />
  26. </el-form-item>
  27. <el-form-item label="APP首页:" prop="app_index">
  28. <el-input v-model="temp.app_index" :size="size" placeholder="请输入APP首页" />
  29. </el-form-item>
  30. <el-form-item v-if="dialogStatus=='update'" label prop="code">
  31. <el-tabs v-model="activeName" @tab-click="handleTabsClick">
  32. <el-tab-pane label="后台菜单" name="first">
  33. <tree-transfer
  34. :title="transferTitle"
  35. :from_data="fromData"
  36. :to_data="selectMenu"
  37. :default-checked-keys="selectedArray"
  38. :default-props="defaultProps"
  39. check-strictly="true"
  40. :mode="mode"
  41. height="350px"
  42. filter
  43. open-all
  44. @addBtn="changeMenu"
  45. @removeBtn="changeMenu"
  46. />
  47. </el-tab-pane>
  48. <el-tab-pane label="APP功能" name="second">
  49. <tree-transfer
  50. :title="transferTitle"
  51. :from_data="appFunfromData"
  52. :to_data="selectAppFun"
  53. :default-checked-keys="selectedAppFunArray"
  54. :default-props="defaultProps"
  55. check-strictly="true"
  56. :mode="mode"
  57. height="350px"
  58. filter
  59. open-all
  60. @addBtn="changeAppFun"
  61. @removeBtn="changeAppFun"
  62. />
  63. </el-tab-pane>
  64. </el-tabs>
  65. </el-form-item>
  66. </el-form>
  67. <footer slot="footer" class="dialog-footer">
  68. <el-button :size="size" @click="dialogVisible = false">{{ $t('common.cancel') }}</el-button>
  69. <el-button :size="size" type="primary" @click="dialogStatus==='create'?createData():updateData()">{{ $t('common.confirm') }}</el-button>
  70. </footer>
  71. </el-dialog>
  72. </el-container>
  73. </template>
  74. <script>
  75. import { mapGetters } from 'vuex'
  76. import { deepClone } from '@/utils/index'
  77. import Sheet from '@/components/Sheet'
  78. import treeTransfer from 'el-tree-transfer'
  79. import OptionSet from '@/components/OptionSet'
  80. import Query from '@/components/Query'
  81. import { role } from './query'
  82. import i18n from '@/i18n'
  83. export default {
  84. name: 'Role',
  85. components: {
  86. Sheet,
  87. treeTransfer,
  88. Query,
  89. OptionSet
  90. },
  91. mixins: [role],
  92. data() {
  93. return {
  94. menu: [],
  95. activeName: 'first',
  96. role_id: '',
  97. fromData: [],
  98. selectMenu: [],
  99. selectedArray: [],
  100. appFunfromData: [],
  101. selectAppFun: [],
  102. selectedAppFunArray: [],
  103. transferTitle: ['Source', 'Target'],
  104. tableColumns: [
  105. {
  106. prop: 'name',
  107. label: i18n.t('Name'),
  108. align: 'center',
  109. minWidth: 180,
  110. maxWidth: 220
  111. },
  112. {
  113. prop: 'code',
  114. label: i18n.t('Code'),
  115. align: 'center',
  116. minWidth: 150,
  117. maxWidth: 180
  118. },
  119. {
  120. prop: 'status',
  121. label: i18n.t('Status'),
  122. align: 'center',
  123. minWidth: 150,
  124. maxWidth: 180
  125. }
  126. ],
  127. operates: {
  128. list: [
  129. { label: 'Edit', show: true, type: 'text', method: (row) => { this.edit(row) } },
  130. { label: 'Del', show: true, type: 'text', method: (row) => { this.deleteData(row) } }
  131. ],
  132. width: 100,
  133. fixed: 'right'
  134. },
  135. dataQuery: {
  136. page: 1,
  137. size: 10,
  138. name: '',
  139. code: ''
  140. },
  141. rules: {
  142. name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  143. code: [{ required: true, message: '请输入编码', trigger: 'blur' }],
  144. status: [{ required: true, message: '请选择状态', trigger: 'blur' }],
  145. admin_index: [
  146. { required: true, message: '请输入后台组件', trigger: 'blur' }
  147. ],
  148. app_index: [
  149. { required: true, message: '请输入app首页', trigger: 'blur' }
  150. ]
  151. },
  152. temp: {
  153. id: undefined,
  154. name: '',
  155. code: '',
  156. admin_index: '',
  157. app_index: ''
  158. },
  159. mode: 'transfer',
  160. defaultProps: {
  161. children: 'nodes',
  162. label: 'name',
  163. value: 'id',
  164. key: 'id'
  165. },
  166. selectionData: [],
  167. dataLoading: false,
  168. dialogStatus: '',
  169. dialogVisible: false
  170. }
  171. },
  172. computed: {
  173. ...mapGetters(['size', 'minMainHeight'])
  174. },
  175. created() {},
  176. methods: {
  177. handleTabsClick(tab, event) {},
  178. getRoleMenuTree(role_id) {
  179. Promise.all([this.$api.sysMenu.tree(), this.$api.sysRole.roleMenuTree({ role_id: role_id })]).then(res => {
  180. this.fromData = res[0].data
  181. this.selectMenu = res[1].data
  182. this.selectedArray = []
  183. this.selectMenu.forEach(item => {
  184. const subSelectId = this.getEndNodes(item)
  185. this.selectedArray = this.selectedArray.concat(subSelectId)
  186. })
  187. })
  188. },
  189. getRoleAppFun(role_id) {
  190. Promise.all([this.$api.sysAppFun.tree(), this.$api.sysRole.roleAppFunTree({ role_id: role_id })]).then(res => {
  191. this.appFunfromData = res[0].data
  192. this.selectAppFun = res[1].data
  193. this.selectedAppFunArray = []
  194. this.selectAppFun.forEach(item => {
  195. const subSelectId = this.getEndNodes(item)
  196. this.selectedAppFunArray = this.selectedAppFunArray.concat(
  197. subSelectId
  198. )
  199. })
  200. })
  201. },
  202. getEndNodes(tree) {
  203. let array = []
  204. tree.nodes.forEach(node => {
  205. if (node.nodes === null || node.nodes.length === 0) {
  206. array.push(node.id)
  207. } else {
  208. array = array.concat(this.getEndNodes(node))
  209. }
  210. })
  211. return array
  212. },
  213. changeMenu(fromData, toData, obj) {
  214. const menuIds = toData.map(x => this.treeToArray(x, 'id')).reduce((acc, curr) => acc.concat(curr), [])
  215. const roleMenus = menuIds.map(x => ({ role_id: this.role_id, menu_id: x }))
  216. this.$api.sysRoleMenu
  217. .batchAdd(roleMenus)
  218. .then(res => {
  219. this.getRoleMenuTree(this.role_id)
  220. })
  221. },
  222. changeAppFun(fromData, toData, obj) {
  223. let app_fun_ids = []
  224. toData.forEach(item => {
  225. const subAppFuns = this.treeToArray(item, 'id')
  226. app_fun_ids = app_fun_ids.concat(subAppFuns)
  227. })
  228. this.$api.app_fun
  229. .AddRoleAppFun({ role_id: this.role_id, app_fun_ids: app_fun_ids })
  230. .then(res => {
  231. this.getAppFunTree(this.role_id)
  232. })
  233. },
  234. treeToArray(data, key) {
  235. let array = []
  236. if (key !== undefined) {
  237. array.push(data[key])
  238. } else {
  239. array.push(data)
  240. }
  241. if (data.nodes === null || data.nodes.length === 0) {
  242. return array
  243. }
  244. data.nodes.forEach(item => {
  245. if (item.nodes != null && item.nodes.length > 0) {
  246. array = array.concat(this.treeToArray(item, key))
  247. } else {
  248. if (key !== undefined) {
  249. array.push(item[key])
  250. } else {
  251. array.push(item)
  252. }
  253. }
  254. })
  255. return array
  256. },
  257. createData() {
  258. this.$refs['dataForm'].validate(valid => {
  259. if (valid) {
  260. this.$api.sysRole.add(this.temp).then(res => {
  261. this.dialogVisible = false
  262. if (res.code === 200) {
  263. this.$message({
  264. message: '创建成功',
  265. type: 'success'
  266. })
  267. this.$refs.qtable.getData()
  268. } else {
  269. this.$message({
  270. message: '创建失败',
  271. type: 'error'
  272. })
  273. }
  274. })
  275. }
  276. })
  277. },
  278. updateData() {
  279. this.$refs['dataForm'].validate(valid => {
  280. if (valid) {
  281. const payload = Object.assign({}, this.temp)
  282. this.$api.sysRole.update(payload).then(res => {
  283. this.dialogVisible = false
  284. this.$message({
  285. message: '修改成功',
  286. type: 'success'
  287. })
  288. this.$refs.qtable.getData()
  289. })
  290. }
  291. })
  292. },
  293. deleteData(row) {
  294. this.$confirm('确认删除?', '提示', {
  295. type: 'warning'
  296. }).then(() => {
  297. this.$api.system.DelRole([{ id: row.id }]).then(res => {
  298. this.$refs.qtable.getData()
  299. this.$message({
  300. message: '删除成功',
  301. type: 'success'
  302. })
  303. })
  304. }).catch(() => {})
  305. },
  306. deleteBatch() {
  307. const ids = this.selectionData.map(row => ({ id: row.id }))
  308. if (ids.length > 0) {
  309. this.$confirm('确认批量删除选中数据吗?', '提示', {
  310. type: 'warning'
  311. }).then(() => {
  312. this.$api.sysRole.batchDel(ids).then(res => {
  313. this.$refs.qtable.getData()
  314. this.$message({
  315. message: '删除成功',
  316. type: 'success'
  317. })
  318. })
  319. }).catch(() => {})
  320. }
  321. },
  322. search(obj) {
  323. this.$refs.qtable.getData(obj)
  324. },
  325. resetFields() {
  326. this.$refs['searchForm'].resetFields()
  327. },
  328. dialogClose() {
  329. this.$refs['dataForm'].resetFields()
  330. },
  331. create() {
  332. this.dialogStatus = 'create'
  333. this.dialogVisible = true
  334. this.$nextTick(() => {
  335. this.$refs['dataForm'].clearValidate()
  336. })
  337. },
  338. edit(row) {
  339. this.dialogStatus = 'update'
  340. this.dialogVisible = true
  341. this.$nextTick(() => {
  342. this.$refs['dataForm'].clearValidate()
  343. this.temp = deepClone(row)
  344. this.role_id = row.id
  345. this.getRoleMenuTree(this.role_id)
  346. this.getRoleAppFun(this.role_id)
  347. })
  348. }
  349. }
  350. }
  351. </script>
  352. <style scoped lang="scss">
  353. </style>