CreateUserDrawer.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <template>
  2. <el-drawer
  3. v-model="isDrawer"
  4. :width="width"
  5. placement="right"
  6. :title="title"
  7. @close="handleReset"
  8. >
  9. <el-form
  10. :model="formParams"
  11. :rules="rules"
  12. ref="formRef"
  13. label-placement="left"
  14. :label-width="80"
  15. >
  16. <el-form-item label="角色编码" prop="roleCode">
  17. <el-input
  18. placeholder="请输入角色编码"
  19. v-model="formParams.roleCode"
  20. :disabled="formParams.roleId ? true : false"
  21. />
  22. </el-form-item>
  23. <el-form-item label="角色名称" prop="roleName">
  24. <el-input placeholder="请输入角色名称" v-model="formParams.roleName" />
  25. </el-form-item>
  26. <el-form-item label="角色权限" prop="permissionIds">
  27. <div class="mark-left"></div>
  28. <el-card shadow="hover" class="permission-card">
  29. <div class="permission-name">场景权限</div>
  30. <el-space>
  31. <el-checkbox v-model:checked="isSpread" @change="packHandle">展开/收起</el-checkbox>
  32. </el-space>
  33. <el-divider />
  34. <div style="height: 25vh">
  35. <el-scrollbar>
  36. <el-tree
  37. ref="treeRef"
  38. node-key="code"
  39. :highlight-current="true"
  40. :data="treeData"
  41. :props="treeProps"
  42. @node-click="clickNode"
  43. />
  44. </el-scrollbar>
  45. </div>
  46. </el-card>
  47. <div style="position: relative; margin-top: 10px; width: 100%">
  48. <div class="mark-left"></div>
  49. <el-card shadow="hover" class="permission-card">
  50. <div class="permission-name">功能权限</div>
  51. <el-space>
  52. <el-checkbox v-model="isAll" @change="handleCheckAll">全选/全不选</el-checkbox>
  53. </el-space>
  54. <el-divider />
  55. <div style="height: 10vh">
  56. <el-scrollbar>
  57. <el-tree
  58. ref="modeTreeRef"
  59. show-checkbox
  60. node-key="key"
  61. :data="modeTreeData"
  62. @check="checkedModeTree"
  63. />
  64. </el-scrollbar>
  65. </div>
  66. </el-card>
  67. </div>
  68. </el-form-item>
  69. <el-form-item label="备注" prop="remark">
  70. <el-input type="textarea" placeholder="请输入备注" v-model="formParams.remark" />
  71. </el-form-item>
  72. </el-form>
  73. <template #footer>
  74. <el-space>
  75. <el-button @click="handleReset">重置</el-button>
  76. <el-button type="primary" :loading="subLoading" @click="formSubmit">提交</el-button>
  77. </el-space>
  78. </template>
  79. </el-drawer>
  80. </template>
  81. <script lang="ts" setup>
  82. import { ref, onMounted, nextTick, computed } from 'vue';
  83. import { ElMessage } from 'element-plus';
  84. import type { userFormParamsType } from './types';
  85. import { addRole, getFeaturePermissions, roleUserInfo, updateRole } from '@/api/system/role';
  86. import useScene from '@/views/system-config/scene-manage/use-scene';
  87. import { storeToRefs } from 'pinia';
  88. const sceneInfos = useScene();
  89. const { tableData } = storeToRefs(sceneInfos);
  90. const { getSceneDetail } = sceneInfos;
  91. // 默认功能权限全部勾选,有未勾选的添加至excludeFeaturePermissionMap中:[workdshopCode]: [permission数组]
  92. const featurePermissionMap = {};
  93. const rules = {
  94. roleCode: {
  95. required: true,
  96. message: '角色编码不能为空',
  97. trigger: 'blur',
  98. },
  99. roleName: {
  100. required: true,
  101. message: '角色名称不能为空',
  102. trigger: 'blur',
  103. },
  104. };
  105. const treeProps = { label: 'name' };
  106. const treeData = computed(() => {
  107. const newList: any[] = [];
  108. if (tableData.value && tableData.value.length) {
  109. for (let i = 0; i < tableData.value.length; i++) {
  110. const data = tableData.value[i];
  111. if (data.children && data.children.length) {
  112. const treeItem = {
  113. id: data.id,
  114. code: data.id,
  115. name: data.name,
  116. children: data
  117. .labelList!.map((item) => {
  118. return {
  119. id: item.id,
  120. code: item.code,
  121. name: item.name,
  122. children: data
  123. .children!.filter((children) => children.sceneLabelId === item.id)
  124. .map((children) => {
  125. return {
  126. id: children.id,
  127. code: children.code,
  128. name: children.name,
  129. isShop: true,
  130. };
  131. }),
  132. };
  133. })
  134. .filter((label) => label.children.length),
  135. };
  136. newList.push(treeItem);
  137. }
  138. }
  139. }
  140. return newList;
  141. });
  142. const modeList = ref<{ key: number; label: string }[]>([]);
  143. const emit = defineEmits(['change']);
  144. const props = defineProps({
  145. title: {
  146. type: String,
  147. default: '添加角色',
  148. },
  149. width: {
  150. type: Number,
  151. default: 450,
  152. },
  153. permissionList: {
  154. type: Array,
  155. },
  156. });
  157. const defaultValueRef = () => ({
  158. roleId: null,
  159. roleName: '',
  160. roleCode: '',
  161. remark: '',
  162. permissions: [],
  163. permissionKeys: [],
  164. });
  165. const defaultTreeValueRef = () => ({
  166. roleId: null,
  167. roleName: '',
  168. roleCode: '',
  169. remark: '',
  170. permissionList: [],
  171. permissionKeys: [],
  172. });
  173. const message = ElMessage;
  174. const formRef: any = ref(null);
  175. const modeTreeRef = ref();
  176. const isDrawer = ref(false);
  177. const subLoading = ref(false);
  178. const isSpread = ref(false);
  179. const isAll = ref(false);
  180. const treeRef = ref();
  181. const expandedKeys = ref();
  182. const selectedNodeKey = ref<string>('');
  183. const modeTreeData = computed(() => (selectedNodeKey.value ? modeList.value : []));
  184. const formParams = ref<userFormParamsType>(defaultTreeValueRef());
  185. function clickNode(tree, nodeInfo, _, __) {
  186. console.log('tree', tree);
  187. console.log('nodeInfo', nodeInfo.data.isShop);
  188. if (nodeInfo.data.isShop) {
  189. selectedNodeKey.value = tree.code;
  190. const checkedNodes = featurePermissionMap[selectedNodeKey.value] || [];
  191. isAll.value = checkedNodes.length >= modeList.value.length;
  192. modeTreeRef.value.setCheckedKeys(checkedNodes);
  193. } else {
  194. selectedNodeKey.value = '';
  195. }
  196. }
  197. function treeNodeExpand(status) {
  198. for (var i = 0; i < treeRef.value.store._getAllNodes().length; i++) {
  199. treeRef.value.store._getAllNodes()[i].expanded = status;
  200. }
  201. }
  202. function packHandle(value) {
  203. if (value) {
  204. treeNodeExpand(true);
  205. expandedKeys.value = props?.permissionList?.map((item: any) => item.key as string) as [];
  206. } else {
  207. expandedKeys.value = [];
  208. treeNodeExpand(false);
  209. }
  210. }
  211. function handleCheckAll(value) {
  212. // if (!value) {
  213. // formParams.value.permissions = [];
  214. // treeRef.value!.setCheckedKeys([]);
  215. // } else {
  216. // const allTreeNodes = treeRef.value.store._getAllNodes().map((item) => item.data.code);
  217. // console.log('allTreeNodes', allTreeNodes.length);
  218. // treeRef.value!.setCheckedKeys(allTreeNodes);
  219. // }
  220. if (!value) {
  221. featurePermissionMap[selectedNodeKey.value] = [];
  222. modeTreeRef.value.setCheckedKeys(featurePermissionMap[selectedNodeKey.value]);
  223. } else {
  224. featurePermissionMap[selectedNodeKey.value] = modeList.value.map((item) => item.key);
  225. modeTreeRef.value.setCheckedKeys(featurePermissionMap[selectedNodeKey.value]);
  226. }
  227. }
  228. // function checkedTree(tree, checkedInfo) {
  229. // console.log(tree);
  230. // console.log(checkedInfo);
  231. // const nodes = checkedInfo.checkedNodes;
  232. // console.log('nodes', nodes);
  233. // const halfKeys = checkedInfo.halfCheckedKeys;
  234. // formParams.value.permissionList = checkedInfo.halfCheckedKeys;
  235. // formParams.value.permissionList = nodes
  236. // .filter((item) => item.isShop)
  237. // .map((node) => {
  238. // return {
  239. // workshopCode: node.code,
  240. // permissionId: '0',
  241. // };
  242. // });
  243. // formParams.value.permissionKeys = halfKeys;
  244. // const allTreeNodes = treeRef.value.store._getAllNodes().map((item) => item.data.code);
  245. // if (nodes.length < allTreeNodes.length) {
  246. // isAll.value = false;
  247. // } else {
  248. // isAll.value = true;
  249. // }
  250. // }
  251. const getPermissionList = () => {
  252. const newPerm = [] as any[];
  253. Object.entries(featurePermissionMap).forEach((item) => {
  254. if (item[0]) {
  255. (item[1] as number[]).forEach((key) => {
  256. newPerm.push({
  257. workshopCode: item[0],
  258. permissionId: key + '',
  259. });
  260. });
  261. }
  262. });
  263. console.log(newPerm);
  264. return newPerm;
  265. };
  266. function checkedModeTree(_, tree) {
  267. isAll.value = tree.checkedKeys.length >= modeList.value.length;
  268. featurePermissionMap[selectedNodeKey.value] = tree.checkedKeys;
  269. }
  270. function openDrawer(roleId?) {
  271. isAll.value = false;
  272. selectedNodeKey.value = '';
  273. if (roleId) {
  274. formParams.value.roleId = roleId;
  275. getInfo();
  276. return;
  277. }
  278. isDrawer.value = true;
  279. }
  280. function closeDrawer() {
  281. isDrawer.value = false;
  282. }
  283. function formSubmit() {
  284. formRef.value.validate((valid) => {
  285. if (!valid) {
  286. return message.error('请填写完整信息');
  287. }
  288. formParams.value.permissionList = getPermissionList();
  289. if (formParams.value.roleId) {
  290. const updateData = {
  291. permissionList: formParams.value.permissionList,
  292. remark: formParams.value.remark,
  293. roleName: formParams.value.roleName,
  294. roleCode: formParams.value.roleCode,
  295. roleType: 3,
  296. roleId: formParams.value.roleId,
  297. };
  298. updateRole(updateData).then((_) => {
  299. message.success('编辑成功');
  300. emit('change');
  301. handleReset();
  302. closeDrawer();
  303. });
  304. } else {
  305. const addData = {
  306. permissionList: formParams.value.permissionList,
  307. remark: formParams.value.remark,
  308. roleName: formParams.value.roleName,
  309. roleCode: formParams.value.roleCode,
  310. roleType: 3,
  311. };
  312. addRole(addData).then((_) => {
  313. message.success('添加成功');
  314. emit('change');
  315. handleReset();
  316. closeDrawer();
  317. });
  318. }
  319. });
  320. }
  321. function handleReset() {
  322. formRef.value.resetFields();
  323. formParams.value = Object.assign(formParams.value, defaultValueRef());
  324. treeRef.value!.setCheckedKeys([]);
  325. // isAll.value = false;
  326. }
  327. function setFeaturePermission(permissionList) {
  328. for (const item of permissionList) {
  329. console.log(item);
  330. if (featurePermissionMap[item.workshopCode]) {
  331. featurePermissionMap[item.workshopCode].push(item.permissionId);
  332. } else {
  333. featurePermissionMap[item.workshopCode] = [item.permissionId];
  334. }
  335. }
  336. }
  337. // const selectNodes = ref<string[]>([]);
  338. function getInfo() {
  339. roleUserInfo({ roleId: formParams.value.roleId }).then((res) => {
  340. const info = {
  341. roleId: res.id,
  342. roleName: res.roleName,
  343. roleCode: res.roleCode,
  344. remark: res.remark,
  345. permissionList: res.permissionIds || [],
  346. permissionKeys: res.permissionKeys || [],
  347. };
  348. formParams.value = info;
  349. isDrawer.value = true;
  350. setFeaturePermission(res.permissionMap);
  351. // nextTick(() => {
  352. // selectNodes.value = res.permissionMap.map((item) => item.workshopCode);
  353. // // 将匹配到的节点的键值数组传递给 setCheckedKeys 方法
  354. // treeRef.value.setCheckedKeys(selectNodes.value);
  355. // });
  356. });
  357. }
  358. onMounted(() => {
  359. getSceneDetail();
  360. getFeaturePermissions().then((res) => {
  361. if (res[0]?.children) {
  362. modeList.value = res[0].children;
  363. }
  364. });
  365. });
  366. defineExpose({
  367. openDrawer,
  368. closeDrawer,
  369. });
  370. </script>
  371. <style scoped>
  372. .mark-left {
  373. position: absolute;
  374. width: 4px;
  375. height: 28px;
  376. top: 0;
  377. background-color: #1890ff;
  378. }
  379. .permission-name {
  380. height: 28px;
  381. font-weight: 500;
  382. display: flex;
  383. align-items: center;
  384. }
  385. :deep(.el-divider--horizontal) {
  386. margin: 12px 0;
  387. }
  388. .permission-card {
  389. width: 100%;
  390. }
  391. :deep(.permission-card .el-card__body) {
  392. padding-top: 0;
  393. }
  394. :deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
  395. color: #409eff;
  396. }
  397. </style>