阅行客电子档案
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
14 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="app-container">
  3. <div class="container-main" style="justify-content: flex-start;">
  4. <!--侧边部门数据-->
  5. <div class="elect-cont-right">
  6. <!--工具栏-->
  7. <div class="head-container">
  8. <div v-if="crud.props.searchToggle" class="head-search">
  9. <!-- 搜索 -->
  10. <el-input v-model="query.blurry" size="small" clearable placeholder="输入部门名称搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @clear="crud.toQuery" @keyup.enter.native="crud.toQuery" />
  11. <date-range-picker v-model="blurryTime" class="date-item" />
  12. <rrOperation />
  13. </div>
  14. <crudOperation :permission="permission">
  15. <template v-slot:right>
  16. <el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)">
  17. <i class="iconfont icon-daochu" />
  18. 导出
  19. </el-button>
  20. </template>
  21. </crudOperation>
  22. </div>
  23. <div class="container-right">
  24. <span class="right-top-line" />
  25. <span class="left-bottom-line" />
  26. <!-- 表单渲染 -->
  27. <el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" class="dialog-middle">
  28. <span class="dialog-right-top" />
  29. <span class="dialog-left-bottom" />
  30. <div class="setting-dialog">
  31. <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="85px">
  32. <el-form-item label="角色名称" prop="name">
  33. <el-input v-model="form.name" />
  34. </el-form-item>
  35. <el-form-item label="描述信息" prop="description">
  36. <el-input v-model="form.description" rows="5" type="textarea" />
  37. </el-form-item>
  38. </el-form>
  39. <div slot="footer" class="dialog-footer">
  40. <el-button type="text" @click="crud.cancelCU">取消</el-button>
  41. <el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确定</el-button>
  42. </div>
  43. </div>
  44. </el-dialog>
  45. <!-- table -->
  46. <el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" :data="crud.data" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
  47. <el-table-column type="selection" align="center" width="55" />
  48. <el-table-column prop="name" label="角色名称" />
  49. <!-- <el-table-column prop="dataScope" label="数据权限" /> -->
  50. <!-- <el-table-column prop="level" label="角色级别" /> -->
  51. <el-table-column :show-overflow-tooltip="true" prop="description" label="描述信息" />
  52. <el-table-column prop="users" label="人数" algin="center">
  53. <template slot-scope="scope">
  54. <div>{{ scope.row.users.length }}</div>
  55. </template>
  56. </el-table-column>
  57. <el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期">
  58. <template slot-scope="scope">
  59. <div>{{ scope.row.createTime | parseTime }}</div>
  60. </template>
  61. </el-table-column>
  62. <!-- <el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="130px" align="center" fixed="right">
  63. <template slot-scope="scope">
  64. <udOperation
  65. v-if="scope.row.level >= level"
  66. :data="scope.row"
  67. :permission="permission"
  68. />
  69. </template>
  70. </el-table-column> -->
  71. </el-table>
  72. <!--分页组件-->
  73. <pagination />
  74. </div>
  75. </div>
  76. <div class="elect-cont-left role-cont-left" style="margin: 0 0 0 20px;">
  77. <div class="container-left">
  78. <span class="right-top-line" />
  79. <span class="left-bottom-line" />
  80. <div slot="header" class="tree-tab">
  81. <el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top">
  82. <span :class="['role-span', {'role-tab-active': roleTabIndex == 0}]" @click="changeActiveTab(0)">菜单分配</span>
  83. </el-tooltip>
  84. <el-tooltip class="item" effect="dark" content="选择指定角色分配全宗范围" placement="top">
  85. <span :class="['role-span', {'role-tab-active': roleTabIndex == 1}]" @click="changeActiveTab(1)">全宗范围</span>
  86. </el-tooltip>
  87. <el-button
  88. v-permission="['admin','roles:edit']"
  89. :disabled="!showButton"
  90. :loading="treeLoading"
  91. size="mini"
  92. @click="saveMenu"
  93. >保存</el-button>
  94. </div>
  95. <el-tree
  96. v-show="roleTabIndex == 0"
  97. ref="menu"
  98. lazy
  99. :data="menus"
  100. :default-checked-keys="menuIds"
  101. :load="getMenuDatas"
  102. :props="defaultProps"
  103. check-strictly
  104. accordion
  105. show-checkbox
  106. node-key="id"
  107. @check="menuChange"
  108. />
  109. <el-tree
  110. v-show="roleTabIndex == 1"
  111. ref="fonds"
  112. lazy
  113. :data="fondDatas"
  114. :default-checked-keys="fondIds"
  115. :load="getFondsDatas"
  116. :props="defaultFondsProps"
  117. check-strictly
  118. accordion
  119. show-checkbox
  120. node-key="id"
  121. @check="fondsChange"
  122. >
  123. <template slot-scope="{ node }">
  124. <el-tooltip :content="node.label" placement="top-end" effect="dark">
  125. <span>{{ node.label }}</span>
  126. </el-tooltip>
  127. </template>
  128. </el-tree>
  129. </div>
  130. </div>
  131. </div>
  132. </div>
  133. </template>
  134. <script>
  135. import crudRoles from '@/api/system/role'
  136. import { FetchFondsAll } from '@/api/system/fonds'
  137. import { getMenusTree, getChild } from '@/api/system/menu'
  138. import CRUD, { presenter, header, form, crud } from '@crud/crud'
  139. import rrOperation from '@crud/RR.operation'
  140. import crudOperation from '@crud/CRUD.operation'
  141. import pagination from '@crud/Pagination'
  142. import DateRangePicker from '@/components/DateRangePicker'
  143. import { exportFile } from '@/utils/index'
  144. import qs from 'qs'
  145. import { mapGetters } from 'vuex'
  146. const defaultForm = { id: null, name: null, description: null, dataScope: null }
  147. export default {
  148. name: 'Role',
  149. components: { pagination, crudOperation, rrOperation, DateRangePicker },
  150. cruds() {
  151. return CRUD({ title: '角色', url: 'api/role/initRoleList', crudMethod: { ...crudRoles }, optShow: {
  152. add: true,
  153. edit: true,
  154. del: true,
  155. reset: true,
  156. download: false,
  157. group: false
  158. }})
  159. },
  160. mixins: [presenter(), header(), form(defaultForm), crud()],
  161. data() {
  162. return {
  163. defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' },
  164. defaultFondsProps: { children: 'children', label: 'fondsName', isLeaf: 'leaf' },
  165. // dateScopes: ['全部', '本级', '自定义'], level: 3,
  166. currentId: 0, treeLoading: false, showButton: false,
  167. menus: [], menuIds: [],
  168. fondDatas: [], fondIds: [],
  169. // depts: [], deptDatas: [], // 多选时使用
  170. permission: {
  171. add: ['admin', 'roles:add'],
  172. edit: ['admin', 'roles:edit'],
  173. del: ['admin', 'roles:del']
  174. },
  175. rules: {
  176. name: [
  177. { required: true, message: '请输入名称', trigger: 'blur' }
  178. ],
  179. permission: [
  180. { required: true, message: '请输入权限', trigger: 'blur' }
  181. ]
  182. },
  183. roleTabIndex: 0,
  184. blurryTime: null,
  185. fondsAllData: [],
  186. getFondsChecked: []
  187. }
  188. },
  189. computed: {
  190. ...mapGetters([
  191. 'baseApi'
  192. ])
  193. },
  194. created() {
  195. },
  196. mounted() {
  197. FetchFondsAll().then(res => {
  198. const resArr = []
  199. res.forEach(item => {
  200. resArr.push({
  201. fondsName: item.fondsName,
  202. id: item.id,
  203. leaf: true
  204. })
  205. })
  206. this.fondsAllData = resArr
  207. })
  208. },
  209. methods: {
  210. changeActiveTab(index) {
  211. this.roleTabIndex = index
  212. },
  213. getMenuDatas(node, resolve) {
  214. setTimeout(() => {
  215. getMenusTree(node.data.id ? node.data.id : 0).then(res => {
  216. resolve(res)
  217. })
  218. }, 100)
  219. },
  220. getFondsDatas(node, resolve) {
  221. if (node.level === 0) {
  222. return resolve([{ fondsName: '全宗选择', id: 0, isChecked: false }])
  223. }
  224. if (node.level > 1) return resolve([])
  225. resolve(this.fondsAllData)
  226. },
  227. [CRUD.HOOK.beforeRefresh]() {
  228. if (this.blurryTime) {
  229. this.crud.query.startTime = this.blurryTime[0]
  230. this.crud.query.endTime = this.blurryTime[1]
  231. }
  232. },
  233. [CRUD.HOOK.afterRefresh]() {
  234. this.$refs.menu.setCheckedKeys([])
  235. this.$refs.fonds.setCheckedKeys([])
  236. },
  237. // 新增前初始化部门信息
  238. [CRUD.HOOK.beforeToAdd](crud, form) {
  239. form.menus = null
  240. form.fondDatas = null
  241. },
  242. // 编辑前初始化自定义数据权限的部门信息
  243. [CRUD.HOOK.beforeToEdit](crud, form) {
  244. // 将角色的菜单清空,避免日志入库数据过长
  245. form.menus = null
  246. form.fondDatas = null
  247. },
  248. // 提交前做的操作
  249. [CRUD.HOOK.afterValidateCU](crud) {
  250. },
  251. // 触发单选
  252. handleCurrentChange(val) {
  253. if (val) {
  254. const _this = this
  255. // 清空菜单的选中
  256. this.$refs.menu.setCheckedKeys([])
  257. this.$refs.fonds.setCheckedKeys([])
  258. // 保存当前的角色id
  259. this.currentId = val.id
  260. // 初始化默认选中的key
  261. this.menuIds = []
  262. this.fondIds = []
  263. val.menus.forEach(function(data) {
  264. _this.menuIds.push(data.id)
  265. })
  266. if (val.fonds) {
  267. if (this.fondsAllData.length === val.fonds.length) {
  268. _this.fondIds.push(0)
  269. }
  270. val.fonds.forEach(function(data) {
  271. _this.fondIds.push(data.id)
  272. })
  273. }
  274. this.showButton = true
  275. }
  276. },
  277. doExport(data) {
  278. crud.downloadLoading = true
  279. this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', {
  280. confirmButtonText: '继续',
  281. cancelButtonText: '取消',
  282. type: 'warning',
  283. dangerouslyUseHTMLString: true
  284. }).then(() => {
  285. const ids = []
  286. data.forEach(val => {
  287. ids.push(val.id)
  288. })
  289. const params = {
  290. 'roleIds': ids
  291. }
  292. exportFile(this.baseApi + '/api/role/exportRole?' + qs.stringify(params, { indices: false }))
  293. }).catch(() => {
  294. })
  295. },
  296. menuChange(menu) {
  297. // 获取该节点的所有子节点,id 包含自身
  298. getChild(menu.id).then(childIds => {
  299. // 判断是否在 menuIds 中,如果存在则删除,否则添加
  300. if (this.menuIds.indexOf(menu.id) !== -1) {
  301. for (let i = 0; i < childIds.length; i++) {
  302. const index = this.menuIds.indexOf(childIds[i])
  303. if (index !== -1) {
  304. this.menuIds.splice(index, 1)
  305. }
  306. }
  307. } else {
  308. for (let i = 0; i < childIds.length; i++) {
  309. const index = this.menuIds.indexOf(childIds[i])
  310. if (index === -1) {
  311. this.menuIds.push(childIds[i])
  312. }
  313. }
  314. }
  315. this.$refs.menu.setCheckedKeys(this.menuIds)
  316. })
  317. },
  318. fondsChange(fonds) {
  319. if (fonds.id === 0) {
  320. fonds.isChecked = !fonds.isChecked
  321. this.fondIds.push(fonds.id)
  322. this.fondsAllData.forEach(childIds => {
  323. if (fonds.isChecked) {
  324. const index = this.fondIds.indexOf(childIds.id)
  325. if (index !== -1) {
  326. this.fondIds.splice(index, 1)
  327. }
  328. this.fondIds.push(childIds.id)
  329. } else {
  330. this.fondIds = []
  331. }
  332. })
  333. } else {
  334. if (this.fondIds.indexOf(fonds.id) !== -1) {
  335. const index = this.fondIds.indexOf(fonds.id)
  336. if (index !== -1) {
  337. this.fondIds.splice(index, 1)
  338. }
  339. } else {
  340. const index = this.fondIds.indexOf(fonds.id)
  341. if (index === -1) {
  342. this.fondIds.push(fonds.id)
  343. }
  344. }
  345. }
  346. this.$refs.fonds.setCheckedKeys(this.fondIds)
  347. },
  348. // 保存菜单
  349. saveMenu() {
  350. this.treeLoading = true
  351. if (this.roleTabIndex === 0) {
  352. const role = { id: this.currentId, menus: [] }
  353. // 得到已选中的 key 值
  354. this.menuIds.forEach(function(id) {
  355. const menu = { id: id }
  356. role.menus.push(menu)
  357. })
  358. crudRoles.editMenu(role).then(() => {
  359. this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
  360. this.treeLoading = false
  361. this.update()
  362. }).catch(err => {
  363. this.treeLoading = false
  364. console.log(err.response.data.message)
  365. })
  366. } else {
  367. const params = { id: this.currentId, fonds: [] }
  368. // 得到已选中的 key 值
  369. this.fondIds.forEach(function(id, index) {
  370. if (id !== 0) {
  371. const fondsArray = { id: id }
  372. params.fonds.push(fondsArray)
  373. }
  374. })
  375. crudRoles.editFonds(params).then(() => {
  376. this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
  377. this.treeLoading = false
  378. }).catch(err => {
  379. console.log(err.response.data.message)
  380. this.treeLoading = false
  381. })
  382. }
  383. },
  384. // 改变数据
  385. update() {
  386. // 无刷新更新 表格数据
  387. crudRoles.get(this.currentId).then(res => {
  388. for (let i = 0; i < this.crud.data.length; i++) {
  389. if (res.id === this.crud.data[i].id) {
  390. this.crud.data[i] = res
  391. break
  392. }
  393. }
  394. })
  395. }
  396. }
  397. }
  398. </script>
  399. <style lang="scss" scoped>
  400. ::v-deep .el-tree .el-tree-node__children .el-tooltip{
  401. width: 150px;
  402. font-size: 14px;
  403. color: #545b65;
  404. white-space: nowrap;
  405. overflow: hidden;
  406. text-overflow: ellipsis;
  407. }
  408. </style>