index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. <template>
  2. <div class="user">
  3. <div class="tree">
  4. <treeList :data="treeListData" v-model="sourceList.pagination.tenantId" node-key="id" @change="treeChange"> </treeList>
  5. </div>
  6. <div class="content">
  7. <byTable
  8. :source="sourceList.data"
  9. :pagination="sourceList.pagination"
  10. :config="config"
  11. :loading="loading"
  12. highlight-current-row
  13. :selectConfig="selectConfig"
  14. searchKey="userName"
  15. :table-events="{
  16. //element talbe事件都能传
  17. select: select,
  18. }"
  19. :action-list="[
  20. {
  21. text: '添加用户',
  22. action: () => openModal('add'),
  23. disabled: !sourceList.pagination.tenantId,
  24. },
  25. ]"
  26. @get-list="getList">
  27. <template #slotName="{ item }">
  28. {{ item.createTime }}
  29. </template>
  30. </byTable>
  31. </div>
  32. <el-dialog :title="modalType == 'add' ? '添加用户' : '编辑用户'" v-if="dialogVisible" v-model="dialogVisible" width="500" v-loading="loading">
  33. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform">
  34. <template #account>
  35. <el-input style="width: 150px; margin-right: 10px" v-model="formData.data.userName" placeholder="请输入用户名"></el-input>
  36. <el-input style="width: 150px; margin-right: 10px" v-model="formData.data.password" placeholder="密码"></el-input>
  37. <span style="color: #409eff; cursor: pointer" @click="newPassword">随机生成</span>
  38. </template>
  39. </byForm>
  40. <template #footer>
  41. <el-button @click="dialogVisible = false" size="large">取 消</el-button>
  42. <el-button type="primary" @click="submitForm('byform')" size="large" :loading="submitLoading">确 定</el-button>
  43. </template>
  44. </el-dialog>
  45. <el-dialog title="修改密码" v-model="roomDialogVisible" width="300" :before-close="handleClose" v-loading="loading">
  46. <template #footer>
  47. <el-input v-model="password" type="password" placeholder="请输入新密码" show-password style="margin-bottom: 20px" />
  48. <el-button @click="roomDialogVisible = false" size="large">取 消</el-button>
  49. <el-button type="primary" @click="submitPassword(password)" size="large" :loading="submitLoading">确 定</el-button>
  50. </template>
  51. </el-dialog>
  52. </div>
  53. </template>
  54. <script setup>
  55. /* eslint-disable vue/no-unused-components */
  56. import { ElMessage, ElMessageBox } from "element-plus";
  57. import byTable from "@/components/byTable/index";
  58. import byForm from "@/components/byForm/index";
  59. import treeList from "@/components/treeList/index";
  60. import { computed, defineComponent, ref } from "vue";
  61. const loading = ref(false);
  62. const submitLoading = ref(false);
  63. const sourceList = ref({
  64. data: [],
  65. pagination: {
  66. total: 3,
  67. pageNum: 1,
  68. pageSize: 10,
  69. },
  70. });
  71. let dialogVisible = ref(false);
  72. let modalType = ref("add");
  73. const validatePass = (rule, value, callback) => {
  74. if (!formData.data.password && modalType.value == "add") {
  75. callback(new Error("请输入账号和密码"));
  76. } else {
  77. callback();
  78. }
  79. };
  80. let rules = ref({
  81. roleKey: [{ required: true, message: "请选择部门", trigger: "blur" }],
  82. nickName: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
  83. userName: [{ validator: validatePass, required: true, message: "请输入账号和密码", trigger: "blur" }],
  84. password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
  85. });
  86. const userId = ref("");
  87. const { proxy } = getCurrentInstance();
  88. const password = ref("");
  89. const roomDialogVisible = ref(false);
  90. const selectConfig = computed(() => {
  91. return [];
  92. });
  93. const config = computed(() => {
  94. return [
  95. {
  96. attrs: {
  97. label: "部门",
  98. prop: "deptName",
  99. },
  100. },
  101. {
  102. attrs: {
  103. label: "姓名",
  104. prop: "nickName",
  105. align: "left",
  106. },
  107. },
  108. {
  109. attrs: {
  110. label: "用户名",
  111. prop: "userName",
  112. },
  113. },
  114. {
  115. attrs: {
  116. label: "系统用户",
  117. prop: "userType",
  118. },
  119. render(userType) {
  120. return userType == 1 ? "是" : "否";
  121. },
  122. },
  123. {
  124. attrs: {
  125. label: "角色",
  126. prop: "sysRoleList",
  127. },
  128. render(sysRoleList) {
  129. return sysRoleList.map((item) => item.roleName).join(",");
  130. },
  131. },
  132. {
  133. attrs: {
  134. label: "手机号",
  135. prop: "phonenumber",
  136. },
  137. },
  138. {
  139. attrs: {
  140. label: "工号",
  141. prop: "jobNumber",
  142. },
  143. },
  144. {
  145. attrs: {
  146. label: "操作",
  147. width: "300",
  148. align: "right",
  149. },
  150. // 渲染 el-button,一般用在最后一列。
  151. renderHTML(row) {
  152. return [
  153. {
  154. attrs: {
  155. label: "修改密码",
  156. type: "primary",
  157. text: true,
  158. },
  159. el: "button",
  160. click() {
  161. console.log(row);
  162. userId.value = row.userId;
  163. roomDialogVisible.value = true;
  164. },
  165. },
  166. {
  167. attrs: {
  168. label: "修改",
  169. type: "primary",
  170. text: true,
  171. },
  172. el: "button",
  173. click() {
  174. if (!sourceList.value.pagination.tenantId) {
  175. ElMessage({
  176. message: "请选择租户",
  177. type: "warning",
  178. });
  179. return;
  180. }
  181. getDtl(row);
  182. },
  183. },
  184. {
  185. attrs: {
  186. label: "删除",
  187. type: "danger",
  188. text: true,
  189. },
  190. el: "button",
  191. click() {
  192. // 弹窗提示是否删除
  193. ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
  194. confirmButtonText: "确定",
  195. cancelButtonText: "取消",
  196. type: "warning",
  197. }).then(() => {
  198. // 删除
  199. proxy
  200. .post(
  201. "/tenantUser/" + row.userId,
  202. {
  203. id: row.userId,
  204. },
  205. "delete"
  206. )
  207. .then((res) => {
  208. ElMessage({
  209. message: "删除成功",
  210. type: "success",
  211. });
  212. getList();
  213. });
  214. });
  215. },
  216. },
  217. ];
  218. },
  219. },
  220. ];
  221. });
  222. let formData = reactive({
  223. data: {},
  224. });
  225. const formOption = reactive({
  226. inline: true,
  227. labelWidth: 100,
  228. itemWidth: 100,
  229. rules: [],
  230. });
  231. const byform = ref(null);
  232. const treeListData = ref([]);
  233. const formConfig = computed(() => {
  234. return [
  235. {
  236. type: "treeSelect",
  237. prop: "deptId",
  238. label: "部门名称",
  239. data: [],
  240. },
  241. {
  242. type: "input",
  243. prop: "nickName",
  244. label: "姓名",
  245. required: true,
  246. itemWidth: 50,
  247. //disabled:true,
  248. itemType: "text",
  249. },
  250. {
  251. type: "slot",
  252. prop: "userName",
  253. slotName: "account",
  254. label: "账户信息",
  255. },
  256. {
  257. type: "radio",
  258. prop: "userType",
  259. label: "系统用户",
  260. required: true,
  261. disabled: true,
  262. border: true,
  263. data: [
  264. {
  265. label: "是",
  266. id: 1,
  267. },
  268. {
  269. label: "否",
  270. id: 0,
  271. },
  272. ],
  273. },
  274. {
  275. type: "select",
  276. label: "角色",
  277. prop: "roleIds",
  278. multiple: true,
  279. data: [],
  280. },
  281. {
  282. type: "input",
  283. prop: "phonenumber",
  284. label: "手机号",
  285. required: true,
  286. itemWidth: 50,
  287. //disabled:true,
  288. itemType: "text",
  289. },
  290. {
  291. type: "input",
  292. prop: "jobNumber",
  293. label: "工号",
  294. required: true,
  295. itemWidth: 50,
  296. //disabled:true,
  297. itemType: "text",
  298. },
  299. ];
  300. });
  301. const newPassword = () => {
  302. formData.data.password = generatePassword();
  303. };
  304. const generatePassword = () => {
  305. var length = 12,
  306. charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
  307. password = "";
  308. for (var i = 0, n = charset.length; i < length; ++i) {
  309. password += charset.charAt(Math.floor(Math.random() * n));
  310. }
  311. return password;
  312. };
  313. const getTreeList = () => {
  314. proxy.post("/tenantInfo/list").then((message) => {
  315. message.map((item) => {
  316. item.label = item.enterpriseName;
  317. item.id = item.tenantId;
  318. item.children = [];
  319. });
  320. treeListData.value = message;
  321. console.log(treeListData.value);
  322. });
  323. };
  324. const getList = async (req) => {
  325. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  326. loading.value = true;
  327. proxy.get("/tenantUser/list", sourceList.value.pagination).then((message) => {
  328. message.rows.map((item) => {
  329. item.deptName = item.dept ? item.dept.deptName : item.dept;
  330. });
  331. sourceList.value.data = message.rows;
  332. sourceList.value.pagination.total = message.total;
  333. setTimeout(() => {
  334. loading.value = false;
  335. }, 200);
  336. });
  337. };
  338. const getUserList = () => {
  339. proxy.get(`/tenantRole/list?pageNum=1&pageSize=10000&tenantId=${sourceList.value.pagination.tenantId}`).then((message) => {
  340. formConfig.value[4].data = message.rows.map((item) => {
  341. return {
  342. ...item,
  343. id: item.roleId,
  344. label: item.roleName,
  345. };
  346. });
  347. });
  348. };
  349. const treeChange = (e) => {
  350. console.log(e);
  351. sourceList.value.pagination.tenantId = e.id;
  352. getList({ tenantId: e.id });
  353. getUserList();
  354. getDept();
  355. };
  356. const openModal = () => {
  357. dialogVisible.value = true;
  358. modalType.value = "add";
  359. formData.data = {
  360. userType: 1,
  361. };
  362. };
  363. const TreetenantId = ref("");
  364. const selection = ref({
  365. data: [],
  366. });
  367. const select = (_selection, row) => {
  368. selection.value.data = _selection;
  369. console.log(_selection.length);
  370. };
  371. const tree = ref(null);
  372. const submitForm = () => {
  373. byform.value.handleSubmit((valid) => {
  374. const method = modalType.value == "add" ? "POST" : "PUT";
  375. console.log(method);
  376. proxy
  377. .post(
  378. "/tenantUser",
  379. {
  380. ...formData.data,
  381. tenantId: sourceList.value.pagination.tenantId,
  382. },
  383. method
  384. )
  385. .then((res) => {
  386. ElMessage({
  387. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  388. type: "success",
  389. });
  390. dialogVisible.value = false;
  391. getList();
  392. getDept();
  393. });
  394. });
  395. };
  396. const recursive = (data) => {
  397. data.map((item) => {
  398. item.label = item.deptName;
  399. item.id = item.deptId;
  400. if (item.children) {
  401. recursive(item.children);
  402. } else {
  403. item.children = [];
  404. }
  405. });
  406. };
  407. const getDept = () => {
  408. proxy
  409. .get("/tenantDept/list", {
  410. pageNum: 1,
  411. tenantId: sourceList.value.pagination.tenantId,
  412. })
  413. .then((message) => {
  414. recursive(message.data);
  415. formConfig.value[0].data = proxy.handleTree(message.data, "deptId");
  416. console.log(formConfig.value[0].data);
  417. });
  418. };
  419. const submitPassword = (password1) => {
  420. if (!password1) {
  421. ElMessage({
  422. message: "请输入新密码",
  423. type: "warning",
  424. });
  425. return;
  426. }
  427. proxy
  428. .post(
  429. "/tenantUser/resetPwd",
  430. {
  431. password: password1,
  432. userId: userId.value,
  433. },
  434. "PUT"
  435. )
  436. .then((res) => {
  437. ElMessage({
  438. message: "重置成功",
  439. type: "success",
  440. });
  441. roomDialogVisible.value = false;
  442. password.value = "";
  443. });
  444. };
  445. const getDtl = (row) => {
  446. //system/user/1
  447. proxy.get(`/tenantUser/${row.userId}`).then((res) => {
  448. console.log(res);
  449. formData.data = { ...row, roleIds: res.roleIds };
  450. modalType.value = "edit";
  451. console.log(modalType.value);
  452. dialogVisible.value = true;
  453. });
  454. };
  455. getTreeList();
  456. getList();
  457. </script>
  458. <style lang="scss" scoped>
  459. .user {
  460. padding: 20px;
  461. display: flex;
  462. justify-content: space-between;
  463. background-color: white;
  464. .tree {
  465. width: 300px;
  466. }
  467. .content {
  468. width: calc(100% - 320px);
  469. }
  470. }
  471. </style>