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