index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  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. attrs: {
  124. label: "角色",
  125. prop: "sysRoleList",
  126. },
  127. render(sysRoleList) {
  128. return sysRoleList.map((item) => item.roleName).join(",")
  129. },
  130. },
  131. {
  132. attrs: {
  133. label: "手机号",
  134. prop: "phonenumber",
  135. },
  136. },
  137. {
  138. attrs: {
  139. label: "工号",
  140. prop: "jobNumber",
  141. },
  142. },
  143. {
  144. attrs: {
  145. label: "操作",
  146. width: "300",
  147. align: "right",
  148. },
  149. // 渲染 el-button,一般用在最后一列。
  150. renderHTML(row) {
  151. return [
  152. {
  153. attrs: {
  154. label: "修改密码",
  155. type: "primary",
  156. text: true,
  157. },
  158. el: "button",
  159. click() {
  160. console.log(row)
  161. userId.value = row.userId;
  162. roomDialogVisible.value = true;
  163. },
  164. },
  165. {
  166. attrs: {
  167. label: "修改",
  168. type: "primary",
  169. text: true,
  170. },
  171. el: "button",
  172. click() {
  173. if (!sourceList.value.pagination.tenantId) {
  174. ElMessage({
  175. message: "请选择租户",
  176. type: "warning",
  177. });
  178. return;
  179. }
  180. getDtl(row);
  181. },
  182. },
  183. {
  184. attrs: {
  185. label: "删除",
  186. type: "danger",
  187. text: true,
  188. },
  189. el: "button",
  190. click() {
  191. // 弹窗提示是否删除
  192. ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
  193. confirmButtonText: "确定",
  194. cancelButtonText: "取消",
  195. type: "warning",
  196. }).then(() => {
  197. // 删除
  198. proxy
  199. .post(
  200. "/tenantUser/" + row.userId,
  201. {
  202. id: row.userId,
  203. },
  204. "delete"
  205. )
  206. .then((res) => {
  207. ElMessage({
  208. message: "删除成功",
  209. type: "success",
  210. });
  211. getList();
  212. });
  213. });
  214. },
  215. },
  216. ];
  217. },
  218. },
  219. ];
  220. });
  221. let formData = reactive({
  222. data: {},
  223. });
  224. const formOption = reactive({
  225. inline: true,
  226. labelWidth: 100,
  227. itemWidth: 100,
  228. rules: [],
  229. });
  230. const byform = ref(null);
  231. const treeListData = ref([]);
  232. const formConfig = computed(() => {
  233. return [
  234. {
  235. type: "treeSelect",
  236. prop: "deptId",
  237. label: "部门名称",
  238. data: [],
  239. },
  240. {
  241. type: "input",
  242. prop: "nickName",
  243. label: "姓名",
  244. required: true,
  245. itemWidth: 50,
  246. //disabled:true,
  247. itemType: "text",
  248. },
  249. {
  250. type: "slot",
  251. prop: "userName",
  252. slotName: "account",
  253. label: "账户信息",
  254. },
  255. {
  256. type: "radio",
  257. prop: "userType",
  258. label: "系统用户",
  259. required: true,
  260. disabled: true,
  261. border: true,
  262. data: [
  263. {
  264. label: "是",
  265. id: 1,
  266. },
  267. {
  268. label: "否",
  269. id: 0,
  270. },
  271. ],
  272. },
  273. {
  274. type: "select",
  275. label: "角色",
  276. prop: "roleIds",
  277. multiple: true,
  278. data: [],
  279. },
  280. {
  281. type: "input",
  282. prop: "phonenumber",
  283. label: "手机号",
  284. required: true,
  285. itemWidth: 50,
  286. //disabled:true,
  287. itemType: "text",
  288. },
  289. {
  290. type: "input",
  291. prop: "jobNumber",
  292. label: "工号",
  293. required: true,
  294. itemWidth: 50,
  295. //disabled:true,
  296. itemType: "text",
  297. },
  298. ];
  299. });
  300. const newPassword = () => {
  301. formData.data.password = generatePassword();
  302. };
  303. const generatePassword = () => {
  304. var length = 12,
  305. charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
  306. password = "";
  307. for (var i = 0, n = charset.length; i < length; ++i) {
  308. password += charset.charAt(Math.floor(Math.random() * n));
  309. }
  310. return password;
  311. };
  312. const getTreeList = () => {
  313. proxy.post("/tenantInfo/list").then((message) => {
  314. message.map((item) => {
  315. item.label = item.enterpriseName;
  316. item.id = item.tenantId;
  317. item.children = [];
  318. });
  319. treeListData.value = message;
  320. console.log(treeListData.value);
  321. });
  322. };
  323. const getList = async (req) => {
  324. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  325. loading.value = true;
  326. proxy.get("/tenantUser/list", sourceList.value.pagination).then((message) => {
  327. message.rows.map((item) => {
  328. item.deptName = item.dept ? item.dept.deptName : item.dept;
  329. });
  330. sourceList.value.data = message.rows;
  331. sourceList.value.pagination.total = message.total;
  332. setTimeout(() => {
  333. loading.value = false;
  334. }, 200);
  335. });
  336. };
  337. const getUserList = () => {
  338. proxy.get(`/tenantRole/list?pageNum=1&pageSize=10000&tenantId=${sourceList.value.pagination.tenantId}`).then((message) => {
  339. formConfig.value[4].data = message.rows.map((item) => {
  340. return {
  341. ...item,
  342. id: item.roleId,
  343. label: item.roleName,
  344. };
  345. });
  346. });
  347. };
  348. const treeChange = (e) => {
  349. console.log(e);
  350. sourceList.value.pagination.tenantId = e.id;
  351. getList({ tenantId: e.id });
  352. getUserList();
  353. getDept();
  354. };
  355. const openModal = () => {
  356. dialogVisible.value = true;
  357. modalType.value = "add";
  358. formData.data = {
  359. userType: 1,
  360. };
  361. };
  362. const TreetenantId = ref("");
  363. const selection = ref({
  364. data: [],
  365. });
  366. const select = (_selection, row) => {
  367. selection.value.data = _selection;
  368. console.log(_selection.length);
  369. };
  370. const tree = ref(null);
  371. const submitForm = () => {
  372. byform.value.handleSubmit((valid) => {
  373. const method = modalType.value == "add" ? "POST" : "PUT";
  374. console.log(method);
  375. proxy
  376. .post(
  377. "/tenantUser",
  378. {
  379. ...formData.data,
  380. tenantId: sourceList.value.pagination.tenantId,
  381. },
  382. method
  383. )
  384. .then((res) => {
  385. ElMessage({
  386. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  387. type: "success",
  388. });
  389. dialogVisible.value = false;
  390. getList();
  391. getDept();
  392. });
  393. });
  394. };
  395. const recursive = (data) => {
  396. data.map((item) => {
  397. item.label = item.deptName;
  398. item.id = item.deptId;
  399. if (item.children) {
  400. recursive(item.children);
  401. } else {
  402. item.children = [];
  403. }
  404. });
  405. };
  406. const getDept = () => {
  407. proxy
  408. .get("/tenantDept/list", {
  409. pageNum: 1,
  410. tenantId: sourceList.value.pagination.tenantId,
  411. })
  412. .then((message) => {
  413. recursive(message.data);
  414. formConfig.value[0].data = proxy.handleTree(message.data, "deptId");
  415. console.log(formConfig.value[0].data);
  416. });
  417. };
  418. const submitPassword = (password1) => {
  419. if (!password1) {
  420. ElMessage({
  421. message: "请输入新密码",
  422. type: "warning",
  423. });
  424. return;
  425. }
  426. proxy
  427. .post(
  428. "/tenantUser/resetPwd",
  429. {
  430. password: password1,
  431. userId: userId.value,
  432. },
  433. "PUT"
  434. )
  435. .then((res) => {
  436. ElMessage({
  437. message: "重置成功",
  438. type: "success",
  439. });
  440. roomDialogVisible.value = false;
  441. password.value = "";
  442. });
  443. };
  444. const getDtl = (row) => {
  445. //system/user/1
  446. proxy.get(`/tenantUser/${row.userId}`).then((res) => {
  447. console.log(res);
  448. formData.data = { ...row, roleIds: res.roleIds };
  449. modalType.value = "edit";
  450. console.log(modalType.value);
  451. dialogVisible.value = true;
  452. });
  453. };
  454. getTreeList();
  455. getList();
  456. </script>
  457. <style lang="scss" scoped>
  458. .user {
  459. padding: 20px;
  460. display: flex;
  461. justify-content: space-between;
  462. .tree {
  463. width: 300px;
  464. }
  465. .content {
  466. width: calc(100% - 320px);
  467. }
  468. }
  469. </style>