index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <template>
  2. <div class="app-container">
  3. <el-container>
  4. <el-aside width="20%">
  5. <div class="slot-tree">
  6. <!-- 异步加载树 -->
  7. <h2 class="tree-title" @click="refreshTree">组织目录</h2>
  8. <el-tree
  9. ref="treeRef"
  10. node-key="id"
  11. :props="resPorp"
  12. :data="orgtreeNodes"
  13. accordion
  14. :highlight-current="true"
  15. @node-click="handleNodeClick"
  16. />
  17. </div>
  18. </el-aside>
  19. <el-main>
  20. <el-card class="box-card">
  21. <div slot="header" class="clearfix">
  22. <div class="filter-container">
  23. <el-input
  24. placeholder="姓名"
  25. style="width: 200px;"
  26. clearable
  27. v-model="listQuery.searchKey"
  28. @keyup.enter.native="handleFilter"
  29. />
  30. <el-select
  31. v-model="listQuery.userStatus"
  32. placeholder="用户状态"
  33. clearable
  34. >
  35. <el-option
  36. v-for="item in userStatus"
  37. :key="item.value"
  38. :label="item.label"
  39. :value="item.value"
  40. >
  41. </el-option>
  42. </el-select>
  43. <el-button
  44. v-waves
  45. type="primary"
  46. icon="el-icon-search"
  47. @click="handleFilter"
  48. >搜索</el-button
  49. >
  50. <el-button
  51. style="margin-left: 10px;"
  52. type="primary"
  53. icon="el-icon-circle-plus-outline"
  54. @click="handleCreate"
  55. >新建</el-button
  56. >
  57. </div>
  58. </div>
  59. <div>
  60. <el-table
  61. v-loading="listLoading"
  62. :key="tableKey"
  63. :data="list"
  64. size="mini"
  65. stripe
  66. border
  67. fit
  68. highlight-current-row
  69. style="width: 100%;"
  70. >
  71. <el-table-column
  72. type="index"
  73. label="序号"
  74. align="center"
  75. width="80"
  76. />
  77. <el-table-column
  78. label="头像"
  79. min-width="80"
  80. align="center"
  81. prop="avatar"
  82. >
  83. <template slot-scope="scope">
  84. <img class="avatar" :src="scope.row.avatar" alt="头像" />
  85. </template>
  86. </el-table-column>
  87. <el-table-column
  88. label="账号"
  89. align="center"
  90. width="180"
  91. prop="account"
  92. />
  93. <el-table-column
  94. label="姓名"
  95. min-width="150"
  96. align="center"
  97. prop="name"
  98. />
  99. <el-table-column
  100. label="性别"
  101. align="center"
  102. width="100"
  103. prop="gender"
  104. />
  105. <el-table-column
  106. label="手机"
  107. align="center"
  108. width="150"
  109. prop="phone"
  110. />
  111. <el-table-column
  112. label="组织"
  113. align="center"
  114. width="150"
  115. prop="orgName"
  116. />
  117. <el-table-column
  118. label="职位"
  119. align="center"
  120. width="150"
  121. prop="positionName"
  122. />
  123. <el-table-column
  124. label="状态"
  125. align="center"
  126. width="150"
  127. prop="userStatus"
  128. >
  129. <template slot-scope="scope">
  130. <el-switch
  131. :value="scope.row.userStatus === 'ENABLE'"
  132. active-color="#13ce66"
  133. inactive-color="#ff4949"
  134. >
  135. </el-switch>
  136. </template>
  137. </el-table-column>
  138. <el-table-column
  139. fixed="right"
  140. label="操作"
  141. align="center"
  142. width="200"
  143. >
  144. <template slot-scope="scope">
  145. <el-tooltip
  146. class="item"
  147. effect="dark"
  148. content="编辑"
  149. placement="top"
  150. >
  151. <el-button
  152. type="primary"
  153. size="mini"
  154. icon="el-icon-edit"
  155. circle
  156. title="编辑"
  157. @click="handleUpdate(scope.row)"
  158. />
  159. </el-tooltip>
  160. <el-tooltip
  161. class="item"
  162. effect="dark"
  163. content="删除"
  164. placement="top"
  165. >
  166. <el-button
  167. size="mini"
  168. type="danger"
  169. icon="el-icon-delete"
  170. circle
  171. title="删除"
  172. @click="handleDelete(scope.row)"
  173. />
  174. </el-tooltip>
  175. <el-tooltip
  176. class="more"
  177. effect="dark"
  178. content="更多"
  179. placement="top"
  180. >
  181. <el-dropdown trigger="click" @command="(command) => handleMore(command, scope.row)">
  182. <el-button
  183. size="mini"
  184. type="primary"
  185. icon="el-icon-more"
  186. circle
  187. title="更多"
  188. />
  189. <el-dropdown-menu class="dropdown-menu" slot="dropdown">
  190. <el-dropdown-item command="reset">重置密码</el-dropdown-item>
  191. </el-dropdown-menu>
  192. </el-dropdown>
  193. </el-tooltip>
  194. </template>
  195. </el-table-column>
  196. </el-table>
  197. <!-- 分页 -->
  198. <swPage
  199. v-if="total > 0"
  200. key="2"
  201. :listQuery="listQuery"
  202. :total="total"
  203. pos="btmRight"
  204. @retPage="retPage"
  205. />
  206. </div>
  207. </el-card>
  208. </el-main>
  209. </el-container>
  210. <!-- 新增或编辑对话框-->
  211. <addUserEditDialog
  212. :propsData="addUserEditDialogDatas"
  213. @refreshTable="refreshData"
  214. />
  215. </div>
  216. </template>
  217. <script>
  218. import waves from "@/directive/waves";
  219. import swPage from "@/views/common/swPage";
  220. import { dynamicTree } from "@/api/auth/position";
  221. import { fetchList, deleteUser,resetPwd } from "@/api/auth/user";
  222. import { positionCategory, userStatus } from "@/constants/index";
  223. import { getValueByKey } from "@/utils/index";
  224. import addUserEditDialog from "./components/addUserEditDialog";
  225. export default {
  226. inject: ["reload"], //刷新
  227. name: "userIndex",
  228. directives: {
  229. waves
  230. },
  231. components: {
  232. swPage,
  233. addUserEditDialog
  234. },
  235. data() {
  236. return {
  237. positionCategory,
  238. userStatus,
  239. tableKey: 0,
  240. orgtreeNodes: [], //组织树节点
  241. currentNode: null,
  242. currNodeData: null, //当前属性的数据
  243. resPorp: {
  244. //树结构
  245. label: "name",
  246. isLeaf: "leaf"
  247. },
  248. list: [],
  249. total: null,
  250. listLoading: false,
  251. listQuery: {
  252. currentPage: 1,
  253. pageSize: 10,
  254. searchKey: null,
  255. orgId: null
  256. },
  257. addUserEditDialogDatas: {
  258. //添加 或者 编辑 dialog 数据
  259. status: "create", //[create ,update]
  260. visible: false,
  261. orgData: null //选中的组织
  262. }
  263. };
  264. },
  265. created() {
  266. this.syncLoadResLabel();
  267. this.getList();
  268. },
  269. methods: {
  270. getValueByKey,
  271. refreshData() {
  272. this.addUserEditDialogDatas.status = "create";
  273. this.addUserEditDialogDatas.visible = false;
  274. this.addUserEditDialogDatas.orgData = null; //选中的组织
  275. this.handleFilter();
  276. },
  277. refreshTree() {
  278. this.syncLoadResLabel();
  279. this.listQuery.currentPage = 1;
  280. this.listQuery.orgId = null;
  281. this.getList();
  282. },
  283. syncLoadResLabel() {
  284. //同步目录
  285. dynamicTree().then(response => {
  286. this.orgtreeNodes = response.data;
  287. });
  288. },
  289. handleNodeClick(data, node) {
  290. //点击node触发
  291. if (this.currentNode && this.currentNode.name === data.name) {
  292. node.checked = !node.checked;
  293. } else {
  294. node.checked = true;
  295. }
  296. if (node.checked) {
  297. // 选中
  298. this.currentNode = data;
  299. this.listQuery.orgId = data.id;
  300. } else {
  301. // 取消选中
  302. this.$refs.treeRef.setCurrentKey(null);
  303. this.currentNode = null;
  304. this.listQuery.orgId = null;
  305. }
  306. this.listQuery.currentPage = 1;
  307. this.getList();
  308. },
  309. getList() {
  310. this.listLoading = true;
  311. fetchList(this.listQuery)
  312. .then(response => {
  313. this.list = response.data.rows;
  314. this.total = response.data.total;
  315. })
  316. .finally(() => {
  317. this.listLoading = false;
  318. });
  319. },
  320. retPage() {
  321. //分页
  322. this.getList();
  323. },
  324. handleFilter() {
  325. this.listQuery.currentPage = 1;
  326. this.getList();
  327. },
  328. handleCreate() {
  329. //查询组织 - 角色
  330. this.addUserEditDialogDatas.status = "create";
  331. this.addUserEditDialogDatas.visible = true;
  332. this.addUserEditDialogDatas.orgData = null;
  333. },
  334. handleUpdate(row) {
  335. //触发更新Dialog和创建的dialog共用一个dialog
  336. this.addUserEditDialogDatas.status = "update";
  337. this.addUserEditDialogDatas.visible = true;
  338. this.addUserEditDialogDatas.orgData = row;
  339. },
  340. handleDelete(row) {
  341. //删除
  342. this.$confirm("确定删除用户?", "提示", {
  343. confirmButtonText: "确定",
  344. cancelButtonText: "取消",
  345. type: "warning"
  346. }).then(() => {
  347. deleteUser([{ userId: row.id }]).then(() => {
  348. this.$notify({
  349. title: "成功",
  350. message: "删除成功",
  351. type: "success",
  352. duration: 3000
  353. });
  354. const index = this.list.indexOf(row);
  355. this.list.splice(index, 1); //数值删除
  356. });
  357. });
  358. },
  359. handleMore(command,row) {
  360. //更多
  361. if(command === 'reset') {
  362. this.handleResetPwd(row)
  363. }
  364. },
  365. handleResetPwd(row) {
  366. //重置密码
  367. this.$confirm("确定重置密码?", "提示", {
  368. confirmButtonText: "确定",
  369. cancelButtonText: "取消",
  370. type: "warning"
  371. }).then(() => {
  372. resetPwd(row).then(() => {
  373. this.$notify({
  374. title: "成功",
  375. message: "重置成功",
  376. type: "success",
  377. duration: 3000
  378. });
  379. });
  380. });
  381. }
  382. }
  383. };
  384. </script>
  385. <style scoped>
  386. .el-aside {
  387. max-width: 200px;
  388. }
  389. /* .filter-container{
  390. display: flex;
  391. align-items: center;
  392. } */
  393. .box-card {
  394. margin-left: 10px;
  395. }
  396. .tree-title {
  397. color: #ae8877;
  398. font-size: 14px;
  399. cursor: pointer;
  400. }
  401. .el-tree-node__content:hover .append {
  402. display: inline !important;
  403. }
  404. .append {
  405. display: none;
  406. }
  407. .avatar {
  408. width: 40px;
  409. height: 40px;
  410. border-radius: 50%;
  411. border: 1px solid #eee;
  412. object-fit: cover;
  413. cursor: pointer;
  414. }
  415. .more {
  416. margin-left: 10px;
  417. }
  418. .dropdown-menu {
  419. .el-dropdown-menu__item {
  420. font-size: 12px;
  421. }
  422. }
  423. </style>