index.vue 9.4 KB

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