index.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <template>
  2. <div class="h-full flex flex-col roleStyle">
  3. <!-- 头部 -->
  4. <div class="bg-white flex justify-between team-header">
  5. <div class="flex items-center justify-between w-full">
  6. <div></div>
  7. <div>
  8. <el-button type="primary" @click="changeRole()">添加角色</el-button>
  9. <el-button type="primary">修改默认角色</el-button>
  10. </div>
  11. </div>
  12. </div>
  13. <!-- 内容 -->
  14. <div class="flex-1 flex">
  15. <div class="flex-1 p-5 overflow-auto">
  16. <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col">
  17. <div class="flex-1 p-3">
  18. <el-table :data="filterTableData" style="width: 100%;height: 100%;" v-bind:loading="allLoading.tableLoading">
  19. <el-table-column label="角色" prop="rolename" width="300" />
  20. <el-table-column label="描述" prop="roleDescribe" />
  21. <el-table-column align="right" width="386">
  22. <template #header>
  23. <el-input v-model="searchRoleName" placeholder="请输入关键字搜索" />
  24. </template>
  25. <template #default="scope">
  26. <el-button @click="changeRole(scope.row)">编辑角色</el-button>
  27. <el-button type="primary" @click="distributionPermissions(scope.row)">分配权限</el-button>
  28. <el-button>导出权限</el-button>
  29. <el-button type="danger" @click="deteleRole(scope.row)">删除</el-button>
  30. </template>
  31. </el-table-column>
  32. </el-table>
  33. </div>
  34. </div>
  35. </div>
  36. </div>
  37. <!-- 添加角色/编辑角色 -->
  38. <el-dialog v-model="allDialogVisible.roleDialogVisible" :title="roleTitle" width="600" :before-close="handleClose">
  39. <div>
  40. <el-form ref="roleFormRef" :model="roleFrom" label-width="auto">
  41. <el-form-item prop="name" label="角色名称" :rules="[
  42. {
  43. required: true,
  44. message: '请输入角色名称',
  45. trigger: 'blur',
  46. },
  47. ]">
  48. <el-input v-model="roleFrom.name" placeholder="请输入角色名称" clearable />
  49. </el-form-item>
  50. <el-form-item label="描述">
  51. <el-input v-model="roleFrom.description" placeholder="请输入描述" type="textarea" clearable />
  52. </el-form-item>
  53. </el-form>
  54. </div>
  55. <template #footer>
  56. <div class="dialog-footer">
  57. <el-button @click="allDialogVisible.roleDialogVisible = false">取消</el-button>
  58. <el-button type="primary" v-bind:loading="allLoading.roleLoading" @click="addRole(roleFormRef)">确定</el-button>
  59. </div>
  60. </template>
  61. </el-dialog>
  62. <!-- 分配权限 -->
  63. <el-dialog v-model="allDialogVisible.permissionsDialogVisible" :title="`分配权限-${permissionsDataItem.rolename}`" width="800"
  64. :before-close="handleClose">
  65. <div class="permissionsData">
  66. <div v-for="(item, index) in permissionsData" :key="index" class="list">
  67. <div class="itemName" v-if="item.name.indexOf('详情') == -1">
  68. <el-checkbox size="large" v-model="item.checked" style="width: 16px; font-weight: bold;"
  69. @change="changeCheckBox(item, true)">{{ item.name }}</el-checkbox>
  70. </div>
  71. <div class="flex-1 flex item">
  72. <div v-for="(list, listIndex) in item.functionList" :key="listIndex" class="itemName">
  73. <el-checkbox size="large" v-model="list.checked" style="width: 16px;"
  74. @change="changeCheckBox(item, false)">{{ list.name }}</el-checkbox>
  75. </div>
  76. <div v-for="(list, listIndex) in item.children" :key="listIndex" class="itemName">
  77. <el-checkbox size="large" v-model="list.checked" style="width: 16px;"
  78. @change="changeCheckBox(item, false)">{{ list.name }}</el-checkbox>
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. <template #footer>
  84. <div class="dialog-footer">
  85. <el-button type="primary" v-bind:loading="allLoading.permissionsLoading" @click="edtPermissions()">保存</el-button>
  86. </div>
  87. </template>
  88. </el-dialog>
  89. </div>
  90. </template>
  91. <script lang="ts" setup>
  92. import { ref, onMounted, reactive, inject, computed } from 'vue';
  93. import { post } from "@/utils/request";
  94. import { GETROLELIST, DETELEROLE, EDITROLE, GETAUTORITY, SAVEPERM } from "./api.ts";
  95. import { FormInstance, ElMessageBox } from 'element-plus'
  96. import { useStore } from '@/store/index'
  97. import { getFromValue, resetFromValue } from '@/utils/tools'
  98. interface roleRuleForm {
  99. id: string
  100. name: string
  101. description: string
  102. }
  103. const { getUserInfoVal } = useStore()
  104. const globalPopup = inject<GlobalPopup>('globalPopup')
  105. const companyId = reactive(getUserInfoVal('companyId') || '')
  106. const searchRoleName = ref('') // 搜索条件
  107. const tableData: any = ref([]) // 表格数据
  108. const permissionsData: any = ref([]) // 权限数据
  109. const permissionsDataItem: any = ref({}) // 选中的权限数据
  110. const roleTitle = ref('添加角色') // 弹窗标题
  111. const roleFormRef = ref<FormInstance>() // 表单ref
  112. const roleFrom = reactive<roleRuleForm>({ // 表单数据
  113. id: '',
  114. name: '',
  115. description: ''
  116. })
  117. const allDialogVisible = reactive({
  118. roleDialogVisible: false,
  119. permissionsDialogVisible: false
  120. })
  121. const allLoading = reactive({
  122. tableLoading: false,
  123. roleLoading: false,
  124. permissionsLoading: false
  125. })
  126. const filterTableData = computed(() =>
  127. tableData.value.filter(
  128. (data: any) =>
  129. !searchRoleName.value ||
  130. data.rolename.toLowerCase().includes(searchRoleName.value.toLowerCase())
  131. )
  132. )
  133. function edtPermissions() {
  134. allLoading.permissionsLoading = true
  135. let moduleList = JSON.stringify(permissionsData.value)
  136. let role = permissionsDataItem.value.id
  137. post(SAVEPERM, { role, moduleList }).then(res => {
  138. if (res.code != 'ok') {
  139. globalPopup?.showError(res.msg)
  140. return
  141. }
  142. globalPopup?.showSuccess('保存成功')
  143. allDialogVisible.permissionsDialogVisible = false
  144. allLoading.permissionsLoading = false
  145. getRoleList()
  146. }).catch(() => {
  147. allLoading.permissionsLoading = false
  148. })
  149. }
  150. function changeCheckBox(item: any, flag: boolean) {
  151. if (flag) {
  152. item.functionList.forEach((list: any) => {
  153. list.checked = item.checked
  154. })
  155. return
  156. }
  157. const { id } = item
  158. let mainMenuList = permissionsData.value;
  159. mainMenuList.forEach((m: any) => {
  160. if (m.id == id) {
  161. var hasChecked = false;
  162. m.functionList.forEach((c: any) => {
  163. if (c.checked) {
  164. hasChecked = true;
  165. }
  166. })
  167. if (hasChecked) {
  168. console.log('执行')
  169. m.checked = hasChecked;
  170. }
  171. }
  172. });
  173. }
  174. function distributionPermissions(item: any) {
  175. const { id } = item
  176. permissionsDataItem.value = item
  177. post(GETAUTORITY, { role: id, companyId }).then(res => {
  178. if (res.code != 'ok') {
  179. globalPopup?.showError(res.msg)
  180. return
  181. }
  182. permissionsData.value = res.data
  183. allDialogVisible.permissionsDialogVisible = true
  184. }).catch(() => {
  185. allDialogVisible.permissionsDialogVisible = true
  186. })
  187. }
  188. function addRole(formEl: FormInstance | undefined) {
  189. if (!formEl) return
  190. let data = getFromValue(roleFrom)
  191. allLoading.roleLoading = true
  192. post(EDITROLE, { ...data, companyId }).then(res => {
  193. if (res.code != 'ok') {
  194. globalPopup?.showError(res.msg)
  195. return
  196. }
  197. globalPopup?.showSuccess('添加成功')
  198. allDialogVisible.roleDialogVisible = false
  199. allLoading.roleLoading = false
  200. getRoleList()
  201. }).catch(() => {
  202. allLoading.roleLoading = false
  203. })
  204. }
  205. function changeRole(item: any = false) {
  206. if (!item) {
  207. resetData()
  208. allDialogVisible.roleDialogVisible = true
  209. }
  210. const { id, rolename, roleDescribe } = JSON.parse(JSON.stringify(item))
  211. Object.assign(roleFrom, { id, name: rolename, description: roleDescribe })
  212. allDialogVisible.roleDialogVisible = true
  213. }
  214. function deteleRole(data: any) {
  215. ElMessageBox.confirm(
  216. `确定删除【${data.rolename}】角色吗?`, '',
  217. {
  218. confirmButtonText: '确定',
  219. cancelButtonText: '取消',
  220. type: 'warning',
  221. }
  222. )
  223. .then(() => {
  224. post(DETELEROLE, { id: data.id }).then(res => {
  225. if (res.code != 'ok') {
  226. globalPopup?.showError(res.msg)
  227. return
  228. }
  229. globalPopup?.showSuccess('删除成功')
  230. getRoleList()
  231. })
  232. })
  233. }
  234. function getRoleList() {
  235. allLoading.tableLoading = true
  236. const companyId = getUserInfoVal('companyId') || ''
  237. post(GETROLELIST, { companyId }).then(res => {
  238. tableData.value = res.data
  239. allLoading.tableLoading = false
  240. }).catch(() => {
  241. allLoading.tableLoading = false
  242. })
  243. }
  244. function resetData() {
  245. let newRoleFrom = resetFromValue(roleFrom)
  246. Object.assign(roleFrom, newRoleFrom)
  247. }
  248. function handleClose(done: any) {
  249. done()
  250. }
  251. onMounted(() => {
  252. getRoleList()
  253. });
  254. </script>
  255. <style lang="scss" scoped>
  256. .roleStyle {
  257. .team-header {
  258. padding: 0.75rem 1.25rem;
  259. }
  260. .permissionsData {
  261. padding: 0 20px 0 40px;
  262. height: 56vh;
  263. overflow: auto;
  264. .bold {
  265. font-weight: bold;
  266. }
  267. .list {
  268. display: flex;
  269. justify-content: space-between;
  270. }
  271. .itemName {
  272. width: 180px;
  273. margin: 0 0 6px 0;
  274. font-size: 16px !important;
  275. }
  276. .item {
  277. flex-wrap: wrap;
  278. }
  279. }
  280. }
  281. </style>