index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. <template>
  2. <div>
  3. <el-card class="box-card">
  4. <byTable
  5. :source="sourceList.data"
  6. :pagination="sourceList.pagination"
  7. :config="config"
  8. :loading="loading"
  9. highlight-current-row
  10. :action-list="[
  11. {
  12. text: '添加账号',
  13. action: () => clickAdd(),
  14. },
  15. ]"
  16. @get-list="getList"
  17. @clickReset="clickReset">
  18. <template #code="{ item }">
  19. <div>
  20. <a style="color: #409eff; cursor: pointer; word-break: break-all" @click="clickCode(item)">{{ item.code }}</a>
  21. </div>
  22. </template>
  23. </byTable>
  24. </el-card>
  25. <el-dialog :title="modalType == 'add' ? '添加账号' : '编辑账号'" v-if="openDialog" v-model="openDialog" width="600">
  26. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
  27. <template #account>
  28. <el-input style="width: 150px; margin-right: 10px" v-model="formData.data.userName" placeholder="请输入用户名"></el-input>
  29. <el-input style="width: 150px; margin-right: 10px" v-model="formData.data.password" placeholder="密码"></el-input>
  30. <span style="color: #409eff; cursor: pointer" @click="newPassword">随机生成</span>
  31. </template>
  32. </byForm>
  33. <template #footer>
  34. <el-button @click="openDialog = false" size="large">取 消</el-button>
  35. <el-button type="primary" @click="submitForm()" size="large" v-preReClick>确 定</el-button>
  36. </template>
  37. </el-dialog>
  38. <el-dialog title="修改密码" v-if="roomDialogVisible" v-model="roomDialogVisible" width="300">
  39. <template #footer>
  40. <el-input v-model="password" type="password" placeholder="请输入新密码" show-password style="margin-bottom: 20px" />
  41. <el-button @click="roomDialogVisible = false" size="large">取 消</el-button>
  42. <el-button type="primary" @click="submitPassword(password)" size="large">确 定</el-button>
  43. </template>
  44. </el-dialog>
  45. </div>
  46. </template>
  47. <script setup>
  48. import byTable from "/src/components/byTable/index";
  49. import { ElMessage, ElMessageBox } from "element-plus";
  50. import byForm from "/src/components/byForm/index";
  51. const { proxy } = getCurrentInstance();
  52. const sourceList = ref({
  53. data: [],
  54. pagination: {
  55. total: 0,
  56. pageNum: 1,
  57. pageSize: 10,
  58. tenantId: "000000",
  59. },
  60. });
  61. const loading = ref(false);
  62. const config = computed(() => {
  63. return [
  64. {
  65. attrs: {
  66. label: "部门",
  67. prop: "deptName",
  68. },
  69. },
  70. {
  71. attrs: {
  72. label: "姓名",
  73. prop: "nickName",
  74. align: "left",
  75. },
  76. },
  77. {
  78. attrs: {
  79. label: "用户名",
  80. prop: "userName",
  81. },
  82. },
  83. {
  84. attrs: {
  85. label: "系统用户",
  86. prop: "userType",
  87. },
  88. render(userType) {
  89. return userType == 1 ? "是" : "否";
  90. },
  91. },
  92. {
  93. attrs: {
  94. label: "角色",
  95. prop: "sysRoleList",
  96. },
  97. render(sysRoleList) {
  98. return sysRoleList.map((item) => item.roleName).join(",");
  99. },
  100. },
  101. {
  102. attrs: {
  103. label: "手机号",
  104. prop: "phonenumber",
  105. },
  106. },
  107. {
  108. attrs: {
  109. label: "工号",
  110. prop: "jobNumber",
  111. },
  112. },
  113. {
  114. attrs: {
  115. label: "操作",
  116. width: 220,
  117. align: "center",
  118. fixed: "right",
  119. },
  120. renderHTML(row) {
  121. return [
  122. {
  123. attrs: {
  124. label: "修改密码",
  125. type: "primary",
  126. text: true,
  127. },
  128. el: "button",
  129. click() {
  130. userId.value = row.userId;
  131. roomDialogVisible.value = true;
  132. },
  133. },
  134. {
  135. attrs: {
  136. label: "编辑",
  137. type: "primary",
  138. text: true,
  139. },
  140. el: "button",
  141. click() {
  142. clickUpdate(row);
  143. },
  144. },
  145. {
  146. attrs: {
  147. label: "删除",
  148. type: "danger",
  149. text: true,
  150. },
  151. el: "button",
  152. click() {
  153. ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
  154. confirmButtonText: "确定",
  155. cancelButtonText: "取消",
  156. type: "warning",
  157. }).then(() => {
  158. proxy
  159. .post(
  160. "/tenantUser/" + row.userId,
  161. {
  162. id: row.userId,
  163. },
  164. "delete"
  165. )
  166. .then(() => {
  167. ElMessage({ message: "删除成功", type: "success" });
  168. getList();
  169. });
  170. });
  171. },
  172. },
  173. ];
  174. },
  175. },
  176. ];
  177. });
  178. const getList = async (req, status) => {
  179. if (status) {
  180. sourceList.value.pagination = {
  181. pageNum: sourceList.value.pagination.pageNum,
  182. pageSize: sourceList.value.pagination.pageSize,
  183. tenantId: "000000",
  184. };
  185. } else {
  186. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  187. }
  188. loading.value = true;
  189. proxy.get("/tenantUser/list", sourceList.value.pagination).then((res) => {
  190. res.rows.map((item) => {
  191. item.deptName = item.dept ? item.dept.deptName : item.dept;
  192. });
  193. sourceList.value.data = res.rows;
  194. sourceList.value.pagination.total = res.total;
  195. setTimeout(() => {
  196. loading.value = false;
  197. }, 200);
  198. });
  199. };
  200. getList();
  201. const clickReset = () => {
  202. getList("", true);
  203. };
  204. const recursive = (data) => {
  205. data.map((item) => {
  206. item.label = item.deptName;
  207. item.id = item.deptId;
  208. if (item.children) {
  209. recursive(item.children);
  210. } else {
  211. item.children = [];
  212. }
  213. });
  214. };
  215. const getDept = () => {
  216. proxy.get(`/tenantRole/list?pageNum=1&pageSize=10000&tenantId=${sourceList.value.pagination.tenantId}`).then((message) => {
  217. formConfig.value[4].data = message.rows.map((item) => {
  218. return {
  219. ...item,
  220. id: item.roleId,
  221. label: item.roleName,
  222. };
  223. });
  224. });
  225. proxy
  226. .get("/tenantDept/list", {
  227. pageNum: 1,
  228. tenantId: sourceList.value.pagination.tenantId,
  229. })
  230. .then((message) => {
  231. recursive(message.data);
  232. formConfig.value[0].data = proxy.handleTree(message.data, "deptId");
  233. });
  234. };
  235. getDept();
  236. const formOption = reactive({
  237. inline: true,
  238. labelWidth: "100px",
  239. itemWidth: 100,
  240. rules: [],
  241. labelPosition: "right",
  242. });
  243. const formData = reactive({
  244. data: {},
  245. treeData: [],
  246. });
  247. const formConfig = computed(() => {
  248. return [
  249. {
  250. type: "treeSelect",
  251. prop: "deptId",
  252. label: "部门名称",
  253. data: [],
  254. },
  255. {
  256. type: "input",
  257. prop: "nickName",
  258. label: "姓名",
  259. required: true,
  260. itemWidth: 50,
  261. itemType: "text",
  262. },
  263. {
  264. type: "slot",
  265. prop: "userName",
  266. slotName: "account",
  267. label: "账户信息",
  268. },
  269. {
  270. type: "radio",
  271. prop: "userType",
  272. label: "系统用户",
  273. required: true,
  274. disabled: true,
  275. border: true,
  276. data: [
  277. {
  278. label: "是",
  279. id: 1,
  280. },
  281. {
  282. label: "否",
  283. id: 0,
  284. },
  285. ],
  286. },
  287. {
  288. type: "select",
  289. label: "角色",
  290. prop: "roleIds",
  291. multiple: true,
  292. data: [],
  293. },
  294. {
  295. type: "input",
  296. prop: "phonenumber",
  297. label: "手机号",
  298. required: true,
  299. itemWidth: 50,
  300. itemType: "text",
  301. },
  302. {
  303. type: "input",
  304. prop: "jobNumber",
  305. label: "工号",
  306. required: true,
  307. itemWidth: 50,
  308. itemType: "text",
  309. },
  310. ];
  311. });
  312. const newPassword = () => {
  313. formData.data.password = generatePassword();
  314. };
  315. const generatePassword = () => {
  316. var length = 12,
  317. charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
  318. password = "";
  319. for (var i = 0, n = charset.length; i < length; ++i) {
  320. password += charset.charAt(Math.floor(Math.random() * n));
  321. }
  322. return password;
  323. };
  324. const validatePass = (rule, value, callback) => {
  325. if (!formData.data.password && modalType.value == "add") {
  326. callback(new Error("请输入账号和密码"));
  327. } else {
  328. callback();
  329. }
  330. };
  331. const rules = ref({
  332. roleKey: [{ required: true, message: "请选择部门", trigger: "blur" }],
  333. nickName: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
  334. userName: [{ validator: validatePass, required: true, message: "请输入账号和密码", trigger: "blur" }],
  335. password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
  336. });
  337. const openDialog = ref(false);
  338. const modalType = ref("add");
  339. const submit = ref(null);
  340. const clickAdd = () => {
  341. modalType.value = "add";
  342. formData.data = {
  343. userType: 1,
  344. tenantId: "000000",
  345. };
  346. openDialog.value = true;
  347. };
  348. const clickUpdate = (item) => {
  349. proxy.get(`/tenantUser/${item.userId}`).then((res) => {
  350. formData.data = { ...item, roleIds: res.roleIds };
  351. modalType.value = "edit";
  352. openDialog.value = true;
  353. });
  354. };
  355. const submitForm = () => {
  356. submit.value.handleSubmit(() => {
  357. const method = modalType.value == "add" ? "POST" : "PUT";
  358. proxy.post("/tenantUser", formData.data, method).then(() => {
  359. ElMessage({
  360. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  361. type: "success",
  362. });
  363. openDialog.value = false;
  364. getList();
  365. });
  366. });
  367. };
  368. const userId = ref("");
  369. const password = ref("");
  370. const roomDialogVisible = ref(false);
  371. const submitPassword = (password1) => {
  372. if (!password1) {
  373. ElMessage({
  374. message: "请输入新密码",
  375. type: "warning",
  376. });
  377. return;
  378. }
  379. proxy
  380. .post(
  381. "/tenantUser/resetPwd",
  382. {
  383. password: password1,
  384. userId: userId.value,
  385. },
  386. "PUT"
  387. )
  388. .then(() => {
  389. ElMessage({ message: "重置成功", type: "success" });
  390. roomDialogVisible.value = false;
  391. password.value = "";
  392. });
  393. };
  394. </script>
  395. <style lang="scss" scoped>
  396. :deep(.el-table__header-wrapper .el-checkbox) {
  397. display: none;
  398. }
  399. </style>