Commit 4dc484f51d28342dd8d14eaaf2581069cc0ba086

Authored by YunaiV
2 parents 8af60fda 82b73994

Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro

ruoyi-ui/src/views/system/user/index.vue
1 -<template>  
2 - <div class="app-container">  
3 - <el-row :gutter="20">  
4 - <!--部门数据-->  
5 - <el-col :span="4" :xs="24">  
6 - <div class="head-container">  
7 - <el-input  
8 - v-model="deptName"  
9 - placeholder="请输入部门名称"  
10 - clearable  
11 - size="small"  
12 - prefix-icon="el-icon-search"  
13 - style="margin-bottom: 20px"  
14 - />  
15 - </div>  
16 - <div class="head-container">  
17 - <el-tree  
18 - :data="deptOptions"  
19 - :props="defaultProps"  
20 - :expand-on-click-node="false"  
21 - :filter-node-method="filterNode"  
22 - ref="tree"  
23 - default-expand-all  
24 - @node-click="handleNodeClick"  
25 - />  
26 - </div>  
27 - </el-col>  
28 - <!--用户数据-->  
29 - <el-col :span="20" :xs="24">  
30 - <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">  
31 - <el-form-item label="用户名称" prop="username">  
32 - <el-input  
33 - v-model="queryParams.username"  
34 - placeholder="请输入用户名称"  
35 - clearable  
36 - size="small"  
37 - style="width: 240px"  
38 - @keyup.enter.native="handleQuery"  
39 - />  
40 - </el-form-item>  
41 - <el-form-item label="手机号码" prop="mobile">  
42 - <el-input  
43 - v-model="queryParams.mobile"  
44 - placeholder="请输入手机号码"  
45 - clearable  
46 - size="small"  
47 - style="width: 240px"  
48 - @keyup.enter.native="handleQuery"  
49 - />  
50 - </el-form-item>  
51 - <el-form-item label="状态" prop="status">  
52 - <el-select  
53 - v-model="queryParams.status"  
54 - placeholder="用户状态"  
55 - clearable  
56 - size="small"  
57 - style="width: 240px"  
58 - >  
59 - <el-option  
60 - v-for="dict in statusDictDatas"  
61 - :key="parseInt(dict.value)"  
62 - :label="dict.label"  
63 - :value="parseInt(dict.value)"  
64 - />  
65 - </el-select>  
66 - </el-form-item>  
67 - <el-form-item label="创建时间">  
68 - <el-date-picker  
69 - v-model="dateRange"  
70 - size="small"  
71 - style="width: 240px"  
72 - value-format="yyyy-MM-dd"  
73 - type="daterange"  
74 - range-separator="-"  
75 - start-placeholder="开始日期"  
76 - end-placeholder="结束日期"  
77 - ></el-date-picker>  
78 - </el-form-item>  
79 - <el-form-item>  
80 - <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>  
81 - <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>  
82 - </el-form-item>  
83 - </el-form>  
84 -  
85 - <el-row :gutter="10" class="mb8">  
86 - <el-col :span="1.5">  
87 - <el-button  
88 - type="primary"  
89 - icon="el-icon-plus"  
90 - size="mini"  
91 - @click="handleAdd"  
92 - v-hasPermi="['system:user:add']"  
93 - >新增</el-button>  
94 - </el-col>  
95 - <el-col :span="1.5">  
96 - <el-button  
97 - type="info"  
98 - icon="el-icon-upload2"  
99 - size="mini"  
100 - @click="handleImport"  
101 - v-hasPermi="['system:user:import']"  
102 - >导入</el-button>  
103 - </el-col>  
104 - <el-col :span="1.5">  
105 - <el-button  
106 - type="warning"  
107 - icon="el-icon-download"  
108 - size="mini"  
109 - @click="handleExport"  
110 - v-hasPermi="['system:user:export']"  
111 - >导出</el-button>  
112 - </el-col>  
113 - <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>  
114 - </el-row>  
115 -  
116 - <el-table v-loading="loading" :data="userList">  
117 - <el-table-column label="用户编号" align="center" prop="id" />  
118 - <el-table-column label="用户名称" align="center" prop="username" :show-overflow-tooltip="true" />  
119 - <el-table-column label="用户昵称" align="center" prop="nickname" :show-overflow-tooltip="true" />  
120 - <el-table-column label="部门" align="center" prop="dept.name" :show-overflow-tooltip="true" />  
121 - <el-table-column label="手机号码" align="center" prop="mobile" width="120" />  
122 - <el-table-column label="状态" align="center">  
123 - <template slot-scope="scope">  
124 - <el-switch  
125 - v-model="scope.row.status"  
126 - :active-value="0"  
127 - :inactive-value="1"  
128 - @change="handleStatusChange(scope.row)"  
129 - ></el-switch>  
130 - </template>  
131 - </el-table-column>  
132 - <el-table-column label="创建时间" align="center" prop="createTime" width="160">  
133 - <template slot-scope="scope">  
134 - <span>{{ parseTime(scope.row.createTime) }}</span>  
135 - </template>  
136 - </el-table-column>  
137 - <el-table-column  
138 - label="操作"  
139 - align="center"  
140 - width="160"  
141 - class-name="small-padding fixed-width"  
142 - >  
143 - <template slot-scope="scope">  
144 - <el-button  
145 - size="mini"  
146 - type="text"  
147 - icon="el-icon-edit"  
148 - @click="handleUpdate(scope.row)"  
149 - v-hasPermi="['system:user:edit']"  
150 - >修改</el-button>  
151 - <el-button  
152 - v-if="scope.row.id !== 1"  
153 - size="mini"  
154 - type="text"  
155 - icon="el-icon-delete"  
156 - @click="handleDelete(scope.row)"  
157 - v-hasPermi="['system:user:remove']"  
158 - >删除</el-button>  
159 - <el-button  
160 - size="mini"  
161 - type="text"  
162 - icon="el-icon-key"  
163 - @click="handleResetPwd(scope.row)"  
164 - v-hasPermi="['system:user:resetPwd']"  
165 - >重置</el-button>  
166 - <el-button  
167 - size="mini"  
168 - type="text"  
169 - icon="el-icon-circle-check"  
170 - @click="handleRole(scope.row)"  
171 - v-hasPermi="['system:permission:assign-user-role']"  
172 - >分配角色</el-button>  
173 - </template>  
174 - </el-table-column>  
175 - </el-table>  
176 -  
177 - <pagination  
178 - v-show="total>0"  
179 - :total="total"  
180 - :page.sync="queryParams.pageNo"  
181 - :limit.sync="queryParams.pageSize"  
182 - @pagination="getList"  
183 - />  
184 - </el-col>  
185 - </el-row>  
186 -  
187 - <!-- 添加或修改参数配置对话框 -->  
188 - <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>  
189 - <el-form ref="form" :model="form" :rules="rules" label-width="80px">  
190 - <el-row>  
191 - <el-col :span="12">  
192 - <el-form-item label="用户昵称" prop="nickname">  
193 - <el-input v-model="form.nickname" placeholder="请输入用户昵称" />  
194 - </el-form-item>  
195 - </el-col>  
196 - <el-col :span="12">  
197 - <el-form-item label="归属部门" prop="deptId">  
198 - <treeselect v-model="form.deptId" :options="deptOptions" :show-count="true"  
199 - placeholder="请选择归属部门" :normalizer="normalizer"  
200 - />  
201 - </el-form-item>  
202 - </el-col>  
203 - </el-row>  
204 - <el-row>  
205 - <el-col :span="12">  
206 - <el-form-item label="手机号码" prop="mobile">  
207 - <el-input v-model="form.mobile" placeholder="请输入手机号码" maxlength="11" />  
208 - </el-form-item>  
209 - </el-col>  
210 - <el-col :span="12">  
211 - <el-form-item label="邮箱" prop="email">  
212 - <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />  
213 - </el-form-item>  
214 - </el-col>  
215 - </el-row>  
216 - <el-row>  
217 - <el-col :span="12">  
218 - <el-form-item v-if="form.id === undefined" label="用户名称" prop="username">  
219 - <el-input v-model="form.username" placeholder="请输入用户名称" />  
220 - </el-form-item>  
221 - </el-col>  
222 - <el-col :span="12">  
223 - <el-form-item v-if="form.id === undefined" label="用户密码" prop="password">  
224 - <el-input v-model="form.password" placeholder="请输入用户密码" type="password" />  
225 - </el-form-item>  
226 - </el-col>  
227 - </el-row>  
228 - <el-row>  
229 - <el-col :span="12">  
230 - <el-form-item label="用户性别">  
231 - <el-select v-model="form.sex" placeholder="请选择">  
232 - <el-option  
233 - v-for="dict in sexDictDatas"  
234 - :key="parseInt(dict.value)"  
235 - :label="dict.label"  
236 - :value="parseInt(dict.value)"  
237 - ></el-option>  
238 - </el-select>  
239 - </el-form-item>  
240 - </el-col>  
241 - <el-col :span="12">  
242 - <el-form-item label="岗位">  
243 - <el-select v-model="form.postIds" multiple placeholder="请选择">  
244 - <el-option  
245 - v-for="item in postOptions"  
246 - :key="item.id"  
247 - :label="item.name"  
248 - :value="item.id"  
249 - ></el-option>  
250 - </el-select>  
251 - </el-form-item>  
252 - </el-col>  
253 - </el-row>  
254 - <el-row>  
255 - <el-col :span="24">  
256 - <el-form-item label="备注">  
257 - <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>  
258 - </el-form-item>  
259 - </el-col>  
260 - </el-row>  
261 - </el-form>  
262 - <div slot="footer" class="dialog-footer">  
263 - <el-button type="primary" @click="submitForm">确 定</el-button>  
264 - <el-button @click="cancel">取 消</el-button>  
265 - </div>  
266 - </el-dialog>  
267 -  
268 - <!-- 用户导入对话框 -->  
269 - <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>  
270 - <el-upload  
271 - ref="upload"  
272 - :limit="1"  
273 - accept=".xlsx, .xls"  
274 - :headers="upload.headers"  
275 - :action="upload.url + '?updateSupport=' + upload.updateSupport"  
276 - :disabled="upload.isUploading"  
277 - :on-progress="handleFileUploadProgress"  
278 - :on-success="handleFileSuccess"  
279 - :auto-upload="false"  
280 - drag  
281 - >  
282 - <i class="el-icon-upload"></i>  
283 - <div class="el-upload__text">  
284 - 将文件拖到此处,或  
285 - <em>点击上传</em>  
286 - </div>  
287 - <div class="el-upload__tip" slot="tip">  
288 - <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据  
289 - <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>  
290 - </div>  
291 - <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>  
292 - </el-upload>  
293 - <div slot="footer" class="dialog-footer">  
294 - <el-button type="primary" @click="submitFileForm">确 定</el-button>  
295 - <el-button @click="upload.open = false">取 消</el-button>  
296 - </div>  
297 - </el-dialog>  
298 -  
299 - <!-- 分配角色 -->  
300 - <el-dialog title="分配角色" :visible.sync="openRole" width="500px" append-to-body>  
301 - <el-form :model="form" label-width="80px">  
302 - <el-form-item label="用户名称">  
303 - <el-input v-model="form.username" :disabled="true" />  
304 - </el-form-item>  
305 - <el-form-item label="用户昵称">  
306 - <el-input v-model="form.nickname" :disabled="true" />  
307 - </el-form-item>  
308 - <el-form-item label="角色">  
309 - <el-select v-model="form.roleIds" multiple placeholder="请选择">  
310 - <el-option  
311 - v-for="item in roleOptions"  
312 - :key="parseInt(item.id)"  
313 - :label="item.name"  
314 - :value="parseInt(item.id)"  
315 - ></el-option>  
316 - </el-select>  
317 - </el-form-item>  
318 - </el-form>  
319 - <div slot="footer" class="dialog-footer">  
320 - <el-button type="primary" @click="submitRole">确 定</el-button>  
321 - <el-button @click="cancelRole">取 消</el-button>  
322 - </div>  
323 - </el-dialog>  
324 -  
325 - </div>  
326 -</template>  
327 -  
328 -<script>  
329 -import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus, importTemplate } from "@/api/system/user";  
330 -import { getToken } from "@/utils/auth";  
331 -import Treeselect from "@riophae/vue-treeselect";  
332 -import "@riophae/vue-treeselect/dist/vue-treeselect.css";  
333 -  
334 -import {listSimpleDepts} from "@/api/system/dept";  
335 -import {listSimplePosts} from "@/api/system/post";  
336 -  
337 -import {SysCommonStatusEnum} from "@/utils/constants";  
338 -import {DICT_TYPE, getDictDatas} from "@/utils/dict";  
339 -import {assignUserRole, listUserRoles} from "@/api/system/permission";  
340 -import {listSimpleRoles} from "@/api/system/role";  
341 -  
342 -export default {  
343 - name: "User",  
344 - components: { Treeselect },  
345 - data() {  
346 - return {  
347 - // 遮罩层  
348 - loading: true,  
349 - // 显示搜索条件  
350 - showSearch: true,  
351 - // 总条数  
352 - total: 0,  
353 - // 用户表格数据  
354 - userList: null,  
355 - // 弹出层标题  
356 - title: "",  
357 - // 部门树选项  
358 - deptOptions: undefined,  
359 - // 是否显示弹出层  
360 - open: false,  
361 - // 部门名称  
362 - deptName: undefined,  
363 - // 默认密码  
364 - initPassword: undefined,  
365 - // 日期范围  
366 - dateRange: [],  
367 - // 状态数据字典  
368 - statusOptions: [],  
369 - // 性别状态字典  
370 - sexOptions: [],  
371 - // 岗位选项  
372 - postOptions: [],  
373 - // 角色选项  
374 - roleOptions: [],  
375 - // 表单参数  
376 - form: {},  
377 - defaultProps: {  
378 - children: "children",  
379 - label: "name"  
380 - },  
381 - // 用户导入参数  
382 - upload: {  
383 - // 是否显示弹出层(用户导入)  
384 - open: false,  
385 - // 弹出层标题(用户导入)  
386 - title: "",  
387 - // 是否禁用上传  
388 - isUploading: false,  
389 - // 是否更新已经存在的用户数据  
390 - updateSupport: 0,  
391 - // 设置上传的请求头部  
392 - headers: { Authorization: "Bearer " + getToken() },  
393 - // 上传的地址  
394 - url: process.env.VUE_APP_BASE_API + '/api/' + "/system/user/import"  
395 - },  
396 - // 查询参数  
397 - queryParams: {  
398 - pageNo: 1,  
399 - pageSize: 10,  
400 - username: undefined,  
401 - mobile: undefined,  
402 - status: undefined,  
403 - deptId: undefined  
404 - },  
405 - // 表单校验  
406 - rules: {  
407 - username: [  
408 - { required: true, message: "用户名称不能为空", trigger: "blur" }  
409 - ],  
410 - nickname: [  
411 - { required: true, message: "用户昵称不能为空", trigger: "blur" }  
412 - ],  
413 - password: [  
414 - { required: true, message: "用户密码不能为空", trigger: "blur" }  
415 - ],  
416 - email: [  
417 - {  
418 - type: "email",  
419 - message: "'请输入正确的邮箱地址",  
420 - trigger: ["blur", "change"]  
421 - }  
422 - ],  
423 - mobile: [  
424 - {  
425 - pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,  
426 - message: "请输入正确的手机号码",  
427 - trigger: "blur"  
428 - }  
429 - ]  
430 - },  
431 - // 是否显示弹出层(角色权限)  
432 - openRole: false,  
433 -  
434 - // 枚举  
435 - SysCommonStatusEnum: SysCommonStatusEnum,  
436 - // 数据字典  
437 - statusDictDatas: getDictDatas(DICT_TYPE.SYS_COMMON_STATUS),  
438 - sexDictDatas: getDictDatas(DICT_TYPE.SYS_USER_SEX),  
439 - };  
440 - },  
441 - watch: {  
442 - // 根据名称筛选部门树  
443 - deptName(val) {  
444 - this.$refs.tree.filter(val);  
445 - }  
446 - },  
447 - created() {  
448 - this.getList();  
449 - this.getTreeselect();  
450 - this.getConfigKey("sys.user.initPassword").then(response => {  
451 - this.initPassword = response.msg;  
452 - });  
453 - },  
454 - methods: {  
455 - /** 查询用户列表 */  
456 - getList() {  
457 - this.loading = true;  
458 - listUser(this.addDateRange(this.queryParams, [  
459 - this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined,  
460 - this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined,  
461 - ])).then(response => {  
462 - this.userList = response.data.list;  
463 - this.total = response.data.total;  
464 - this.loading = false;  
465 - }  
466 - );  
467 - },  
468 - /** 查询部门下拉树结构 + 岗位下拉 */  
469 - getTreeselect() {  
470 - listSimpleDepts().then(response => {  
471 - // 处理 deptOptions 参数  
472 - this.deptOptions = [];  
473 - this.deptOptions.push(...this.handleTree(response.data, "id"));  
474 - });  
475 - listSimplePosts().then(response => {  
476 - // 处理 postOptions 参数  
477 - this.postOptions = [];  
478 - this.postOptions.push(...response.data);  
479 - });  
480 - },  
481 - // 筛选节点  
482 - filterNode(value, data) {  
483 - if (!value) return true;  
484 - return data.name.indexOf(value) !== -1;  
485 - },  
486 - // 节点单击事件  
487 - handleNodeClick(data) {  
488 - this.queryParams.deptId = data.id;  
489 - this.getList();  
490 - },  
491 - // 用户状态修改  
492 - handleStatusChange(row) {  
493 - let text = row.status === SysCommonStatusEnum.ENABLE ? "启用" : "停用";  
494 - this.$confirm('确认要"' + text + '""' + row.username + '"用户吗?', "警告", {  
495 - confirmButtonText: "确定",  
496 - cancelButtonText: "取消",  
497 - type: "warning"  
498 - }).then(function() {  
499 - return changeUserStatus(row.id, row.status);  
500 - }).then(() => {  
501 - this.msgSuccess(text + "成功");  
502 - }).catch(function() {  
503 - row.status = row.status === SysCommonStatusEnum.ENABLE ? SysCommonStatusEnum.DISABLE  
504 - : SysCommonStatusEnum.ENABLE;  
505 - });  
506 - },  
507 - // 取消按钮  
508 - cancel() {  
509 - this.open = false;  
510 - this.reset();  
511 - },  
512 - // 取消按钮(角色权限)  
513 - cancelRole() {  
514 - this.openRole = false;  
515 - this.reset();  
516 - },  
517 - // 表单重置  
518 - reset() {  
519 - this.form = {  
520 - id: undefined,  
521 - deptId: undefined,  
522 - username: undefined,  
523 - nickname: undefined,  
524 - password: undefined,  
525 - mobile: undefined,  
526 - email: undefined,  
527 - sex: undefined,  
528 - status: "0",  
529 - remark: undefined,  
530 - postIds: [],  
531 - roleIds: []  
532 - };  
533 - this.resetForm("form");  
534 - },  
535 - /** 搜索按钮操作 */  
536 - handleQuery() {  
537 - this.queryParams.pageNo = 1;  
538 - this.getList();  
539 - },  
540 - /** 重置按钮操作 */  
541 - resetQuery() {  
542 - this.dateRange = [];  
543 - this.resetForm("queryForm");  
544 - this.handleQuery();  
545 - },  
546 - /** 新增按钮操作 */  
547 - handleAdd() {  
548 - this.reset();  
549 - // 获得下拉数据  
550 - this.getTreeselect();  
551 - // 打开表单,并设置初始化  
552 - this.open = true;  
553 - this.title = "添加用户";  
554 - this.form.password = this.initPassword;  
555 - },  
556 - /** 修改按钮操作 */  
557 - handleUpdate(row) {  
558 - this.reset();  
559 - this.getTreeselect();  
560 - const id = row.id;  
561 - getUser(id).then(response => {  
562 - this.form = response.data;  
563 - this.open = true;  
564 - this.title = "修改用户";  
565 - this.form.password = "";  
566 - });  
567 - },  
568 - /** 重置密码按钮操作 */  
569 - handleResetPwd(row) {  
570 - this.$prompt('请输入"' + row.username + '"的新密码', "提示", {  
571 - confirmButtonText: "确定",  
572 - cancelButtonText: "取消"  
573 - }).then(({ value }) => {  
574 - resetUserPwd(row.id, value).then(response => {  
575 - this.msgSuccess("修改成功,新密码是:" + value);  
576 - });  
577 - }).catch(() => {});  
578 - },  
579 - /** 分配用户角色操作 */  
580 - handleRole(row) {  
581 - this.reset();  
582 - const id = row.id  
583 - // 处理了 form 的用户 username 和 nickname 的展示  
584 - this.form.id = id;  
585 - this.form.username = row.username;  
586 - this.form.nickname = row.nickname;  
587 - // 打开弹窗  
588 - this.openRole = true;  
589 - // 获得角色列表  
590 - listSimpleRoles().then(response => {  
591 - // 处理 roleOptions 参数  
592 - this.roleOptions = [];  
593 - this.roleOptions.push(...response.data);  
594 - });  
595 - // 获得角色拥有的菜单集合  
596 - listUserRoles(id).then(response => {  
597 - // 设置选中  
598 - this.form.roleIds = response.data;  
599 - })  
600 - },  
601 - /** 提交按钮 */  
602 - submitForm: function() {  
603 - this.$refs["form"].validate(valid => {  
604 - if (valid) {  
605 - if (this.form.id !== undefined) {  
606 - updateUser(this.form).then(response => {  
607 - this.msgSuccess("修改成功");  
608 - this.open = false;  
609 - this.getList();  
610 - });  
611 - } else {  
612 - addUser(this.form).then(response => {  
613 - this.msgSuccess("新增成功");  
614 - this.open = false;  
615 - this.getList();  
616 - });  
617 - }  
618 - }  
619 - });  
620 - },  
621 - /** 提交按钮(角色权限) */  
622 - submitRole: function() {  
623 - if (this.form.id !== undefined) {  
624 - assignUserRole({  
625 - userId: this.form.id,  
626 - roleIds: this.form.roleIds,  
627 - }).then(response => {  
628 - this.msgSuccess("分配角色成功");  
629 - this.openRole = false;  
630 - this.getList();  
631 - });  
632 - }  
633 - },  
634 - /** 删除按钮操作 */  
635 - handleDelete(row) {  
636 - const ids = row.id || this.ids;  
637 - this.$confirm('是否确认删除用户编号为"' + ids + '"的数据项?', "警告", {  
638 - confirmButtonText: "确定",  
639 - cancelButtonText: "取消",  
640 - type: "warning"  
641 - }).then(function() {  
642 - return delUser(ids);  
643 - }).then(() => {  
644 - this.getList();  
645 - this.msgSuccess("删除成功");  
646 - })  
647 - },  
648 - /** 导出按钮操作 */  
649 - handleExport() {  
650 - const queryParams = this.addDateRange(this.queryParams, [  
651 - this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined,  
652 - this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined,  
653 - ]);  
654 - this.$confirm('是否确认导出所有用户数据项?', "警告", {  
655 - confirmButtonText: "确定",  
656 - cancelButtonText: "取消",  
657 - type: "warning"  
658 - }).then(function() {  
659 - return exportUser(queryParams);  
660 - }).then(response => {  
661 - this.downloadExcel(response, '用户数据.xls');  
662 - })  
663 - },  
664 - /** 导入按钮操作 */  
665 - handleImport() {  
666 - this.upload.title = "用户导入";  
667 - this.upload.open = true;  
668 - },  
669 - /** 下载模板操作 */  
670 - importTemplate() {  
671 - importTemplate().then(response => {  
672 - this.downloadExcel(response, '用户导入模板.xls');  
673 - });  
674 - },  
675 - // 文件上传中处理  
676 - handleFileUploadProgress(event, file, fileList) {  
677 - this.upload.isUploading = true;  
678 - },  
679 - // 文件上传成功处理  
680 - handleFileSuccess(response, file, fileList) {  
681 - this.upload.open = false;  
682 - this.upload.isUploading = false;  
683 - this.$refs.upload.clearFiles();  
684 - // 拼接提示语  
685 - let data = response.data;  
686 - let text = '创建成功数量:' + data.createUsernames.length;  
687 - for (const username of data.createUsernames) {  
688 - text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username;  
689 - }  
690 - text += '<br />更新成功数量:' + data.updateUsernames.length;  
691 - for (const username of data.updateUsernames) {  
692 - text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username;  
693 - }  
694 - text += '<br />更新失败数量:' + Object.keys(data.failureUsernames).length;  
695 - for (const username in data.failureUsernames) {  
696 - text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username + ':' + data.failureUsernames[username];  
697 - }  
698 - this.$alert(text, "导入结果", { dangerouslyUseHTMLString: true });  
699 - this.getList();  
700 - },  
701 - // 提交上传文件  
702 - submitFileForm() {  
703 - this.$refs.upload.submit();  
704 - },  
705 - // 格式化部门的下拉框  
706 - normalizer(node) {  
707 - return {  
708 - id: node.id,  
709 - label: node.name,  
710 - children: node.children  
711 - }  
712 - }  
713 - }  
714 -};  
715 -</script> 1 +<template>
  2 + <div class="app-container">
  3 + <el-row :gutter="20">
  4 + <!--部门数据-->
  5 + <el-col :span="4" :xs="24">
  6 + <div class="head-container">
  7 + <el-input
  8 + v-model="deptName"
  9 + placeholder="请输入部门名称"
  10 + clearable
  11 + size="small"
  12 + prefix-icon="el-icon-search"
  13 + style="margin-bottom: 20px"
  14 + />
  15 + </div>
  16 + <div class="head-container">
  17 + <el-tree
  18 + :data="deptOptions"
  19 + :props="defaultProps"
  20 + :expand-on-click-node="false"
  21 + :filter-node-method="filterNode"
  22 + ref="tree"
  23 + default-expand-all
  24 + @node-click="handleNodeClick"
  25 + />
  26 + </div>
  27 + </el-col>
  28 + <!--用户数据-->
  29 + <el-col :span="20" :xs="24">
  30 + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  31 + <el-form-item label="用户名称" prop="username">
  32 + <el-input
  33 + v-model="queryParams.username"
  34 + placeholder="请输入用户名称"
  35 + clearable
  36 + size="small"
  37 + style="width: 240px"
  38 + @keyup.enter.native="handleQuery"
  39 + />
  40 + </el-form-item>
  41 + <el-form-item label="手机号码" prop="mobile">
  42 + <el-input
  43 + v-model="queryParams.mobile"
  44 + placeholder="请输入手机号码"
  45 + clearable
  46 + size="small"
  47 + style="width: 240px"
  48 + @keyup.enter.native="handleQuery"
  49 + />
  50 + </el-form-item>
  51 + <el-form-item label="状态" prop="status">
  52 + <el-select
  53 + v-model="queryParams.status"
  54 + placeholder="用户状态"
  55 + clearable
  56 + size="small"
  57 + style="width: 240px"
  58 + >
  59 + <el-option
  60 + v-for="dict in statusDictDatas"
  61 + :key="parseInt(dict.value)"
  62 + :label="dict.label"
  63 + :value="parseInt(dict.value)"
  64 + />
  65 + </el-select>
  66 + </el-form-item>
  67 + <el-form-item label="创建时间">
  68 + <el-date-picker
  69 + v-model="dateRange"
  70 + size="small"
  71 + style="width: 240px"
  72 + value-format="yyyy-MM-dd"
  73 + type="daterange"
  74 + range-separator="-"
  75 + start-placeholder="开始日期"
  76 + end-placeholder="结束日期"
  77 + ></el-date-picker>
  78 + </el-form-item>
  79 + <el-form-item>
  80 + <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  81 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  82 + </el-form-item>
  83 + </el-form>
  84 +
  85 + <el-row :gutter="10" class="mb8">
  86 + <el-col :span="1.5">
  87 + <el-button
  88 + type="primary"
  89 + icon="el-icon-plus"
  90 + size="mini"
  91 + @click="handleAdd"
  92 + v-hasPermi="['system:user:add']"
  93 + >新增</el-button>
  94 + </el-col>
  95 + <el-col :span="1.5">
  96 + <el-button
  97 + type="info"
  98 + icon="el-icon-upload2"
  99 + size="mini"
  100 + @click="handleImport"
  101 + v-hasPermi="['system:user:import']"
  102 + >导入</el-button>
  103 + </el-col>
  104 + <el-col :span="1.5">
  105 + <el-button
  106 + type="warning"
  107 + icon="el-icon-download"
  108 + size="mini"
  109 + @click="handleExport"
  110 + v-hasPermi="['system:user:export']"
  111 + >导出</el-button>
  112 + </el-col>
  113 + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  114 + </el-row>
  115 +
  116 + <el-table v-loading="loading" :data="userList">
  117 + <el-table-column label="用户编号" align="center" prop="id" />
  118 + <el-table-column label="用户名称" align="center" prop="username" :show-overflow-tooltip="true" />
  119 + <el-table-column label="用户昵称" align="center" prop="nickname" :show-overflow-tooltip="true" />
  120 + <el-table-column label="部门" align="center" prop="dept.name" :show-overflow-tooltip="true" />
  121 + <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
  122 + <el-table-column label="状态" align="center">
  123 + <template slot-scope="scope">
  124 + <el-switch
  125 + v-model="scope.row.status"
  126 + :active-value="0"
  127 + :inactive-value="1"
  128 + @change="handleStatusChange(scope.row)"
  129 + ></el-switch>
  130 + </template>
  131 + </el-table-column>
  132 + <el-table-column label="创建时间" align="center" prop="createTime" width="160">
  133 + <template slot-scope="scope">
  134 + <span>{{ parseTime(scope.row.createTime) }}</span>
  135 + </template>
  136 + </el-table-column>
  137 + <el-table-column
  138 + label="操作"
  139 + align="center"
  140 + width="160"
  141 + class-name="small-padding fixed-width"
  142 + >
  143 + <template slot-scope="scope">
  144 + <el-button
  145 + size="large"
  146 + type="text"
  147 + icon="el-icon-edit"
  148 + @click="handleUpdate(scope.row)"
  149 + v-hasPermi="['system:role:edit']"
  150 + >修改</el-button>
  151 + <el-dropdown @command="(command) => handleCommand(command, scope.$index, scope.row)">
  152 + <span class="el-dropdown-link">
  153 + 更多操作<i class="el-icon-arrow-down el-icon--right"></i>
  154 + </span>
  155 + <el-dropdown-menu slot="dropdown">
  156 + <el-dropdown-item
  157 + command="handleDelete"
  158 + v-if="scope.row.id !== 1"
  159 + size="mini"
  160 + type="text"
  161 + icon="el-icon-delete"
  162 + v-hasPermi="['system:user:remove']"
  163 + >删除</el-dropdown-item>
  164 + <el-dropdown-item
  165 + command="handleResetPwd"
  166 + size="mini"
  167 + type="text"
  168 + icon="el-icon-key"
  169 + v-hasPermi="['system:user:resetPwd']"
  170 + >重置</el-dropdown-item>
  171 + <el-dropdown-item
  172 + command="handleRole"
  173 + size="mini"
  174 + type="text"
  175 + icon="el-icon-circle-check"
  176 + v-hasPermi="['system:permission:assign-user-role']"
  177 + >分配角色</el-dropdown-item>
  178 + </el-dropdown-menu>
  179 + </el-dropdown>
  180 + </template>
  181 + </el-table-column>
  182 + </el-table>
  183 +
  184 + <pagination
  185 + v-show="total>0"
  186 + :total="total"
  187 + :page.sync="queryParams.pageNo"
  188 + :limit.sync="queryParams.pageSize"
  189 + @pagination="getList"
  190 + />
  191 + </el-col>
  192 + </el-row>
  193 +
  194 + <!-- 添加或修改参数配置对话框 -->
  195 + <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
  196 + <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  197 + <el-row>
  198 + <el-col :span="12">
  199 + <el-form-item label="用户昵称" prop="nickname">
  200 + <el-input v-model="form.nickname" placeholder="请输入用户昵称" />
  201 + </el-form-item>
  202 + </el-col>
  203 + <el-col :span="12">
  204 + <el-form-item label="归属部门" prop="deptId">
  205 + <treeselect v-model="form.deptId" :options="deptOptions" :show-count="true"
  206 + placeholder="请选择归属部门" :normalizer="normalizer"
  207 + />
  208 + </el-form-item>
  209 + </el-col>
  210 + </el-row>
  211 + <el-row>
  212 + <el-col :span="12">
  213 + <el-form-item label="手机号码" prop="mobile">
  214 + <el-input v-model="form.mobile" placeholder="请输入手机号码" maxlength="11" />
  215 + </el-form-item>
  216 + </el-col>
  217 + <el-col :span="12">
  218 + <el-form-item label="邮箱" prop="email">
  219 + <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
  220 + </el-form-item>
  221 + </el-col>
  222 + </el-row>
  223 + <el-row>
  224 + <el-col :span="12">
  225 + <el-form-item v-if="form.id === undefined" label="用户名称" prop="username">
  226 + <el-input v-model="form.username" placeholder="请输入用户名称" />
  227 + </el-form-item>
  228 + </el-col>
  229 + <el-col :span="12">
  230 + <el-form-item v-if="form.id === undefined" label="用户密码" prop="password">
  231 + <el-input v-model="form.password" placeholder="请输入用户密码" type="password" />
  232 + </el-form-item>
  233 + </el-col>
  234 + </el-row>
  235 + <el-row>
  236 + <el-col :span="12">
  237 + <el-form-item label="用户性别">
  238 + <el-select v-model="form.sex" placeholder="请选择">
  239 + <el-option
  240 + v-for="dict in sexDictDatas"
  241 + :key="parseInt(dict.value)"
  242 + :label="dict.label"
  243 + :value="parseInt(dict.value)"
  244 + ></el-option>
  245 + </el-select>
  246 + </el-form-item>
  247 + </el-col>
  248 + <el-col :span="12">
  249 + <el-form-item label="岗位">
  250 + <el-select v-model="form.postIds" multiple placeholder="请选择">
  251 + <el-option
  252 + v-for="item in postOptions"
  253 + :key="item.id"
  254 + :label="item.name"
  255 + :value="item.id"
  256 + ></el-option>
  257 + </el-select>
  258 + </el-form-item>
  259 + </el-col>
  260 + </el-row>
  261 + <el-row>
  262 + <el-col :span="24">
  263 + <el-form-item label="备注">
  264 + <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
  265 + </el-form-item>
  266 + </el-col>
  267 + </el-row>
  268 + </el-form>
  269 + <div slot="footer" class="dialog-footer">
  270 + <el-button type="primary" @click="submitForm">确 定</el-button>
  271 + <el-button @click="cancel">取 消</el-button>
  272 + </div>
  273 + </el-dialog>
  274 +
  275 + <!-- 用户导入对话框 -->
  276 + <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
  277 + <el-upload
  278 + ref="upload"
  279 + :limit="1"
  280 + accept=".xlsx, .xls"
  281 + :headers="upload.headers"
  282 + :action="upload.url + '?updateSupport=' + upload.updateSupport"
  283 + :disabled="upload.isUploading"
  284 + :on-progress="handleFileUploadProgress"
  285 + :on-success="handleFileSuccess"
  286 + :auto-upload="false"
  287 + drag
  288 + >
  289 + <i class="el-icon-upload"></i>
  290 + <div class="el-upload__text">
  291 + 将文件拖到此处,或
  292 + <em>点击上传</em>
  293 + </div>
  294 + <div class="el-upload__tip" slot="tip">
  295 + <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
  296 + <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
  297 + </div>
  298 + <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
  299 + </el-upload>
  300 + <div slot="footer" class="dialog-footer">
  301 + <el-button type="primary" @click="submitFileForm">确 定</el-button>
  302 + <el-button @click="upload.open = false">取 消</el-button>
  303 + </div>
  304 + </el-dialog>
  305 +
  306 + <!-- 分配角色 -->
  307 + <el-dialog title="分配角色" :visible.sync="openRole" width="500px" append-to-body>
  308 + <el-form :model="form" label-width="80px">
  309 + <el-form-item label="用户名称">
  310 + <el-input v-model="form.username" :disabled="true" />
  311 + </el-form-item>
  312 + <el-form-item label="用户昵称">
  313 + <el-input v-model="form.nickname" :disabled="true" />
  314 + </el-form-item>
  315 + <el-form-item label="角色">
  316 + <el-select v-model="form.roleIds" multiple placeholder="请选择">
  317 + <el-option
  318 + v-for="item in roleOptions"
  319 + :key="parseInt(item.id)"
  320 + :label="item.name"
  321 + :value="parseInt(item.id)"
  322 + ></el-option>
  323 + </el-select>
  324 + </el-form-item>
  325 + </el-form>
  326 + <div slot="footer" class="dialog-footer">
  327 + <el-button type="primary" @click="submitRole">确 定</el-button>
  328 + <el-button @click="cancelRole">取 消</el-button>
  329 + </div>
  330 + </el-dialog>
  331 +
  332 + </div>
  333 +</template>
  334 +
  335 +<script>
  336 +import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus, importTemplate } from "@/api/system/user";
  337 +import { getToken } from "@/utils/auth";
  338 +import Treeselect from "@riophae/vue-treeselect";
  339 +import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  340 +
  341 +import {listSimpleDepts} from "@/api/system/dept";
  342 +import {listSimplePosts} from "@/api/system/post";
  343 +
  344 +import {SysCommonStatusEnum} from "@/utils/constants";
  345 +import {DICT_TYPE, getDictDatas} from "@/utils/dict";
  346 +import {assignUserRole, listUserRoles} from "@/api/system/permission";
  347 +import {listSimpleRoles} from "@/api/system/role";
  348 +
  349 +export default {
  350 + name: "User",
  351 + components: { Treeselect },
  352 + data() {
  353 + return {
  354 + // 遮罩层
  355 + loading: true,
  356 + // 显示搜索条件
  357 + showSearch: true,
  358 + // 总条数
  359 + total: 0,
  360 + // 用户表格数据
  361 + userList: null,
  362 + // 弹出层标题
  363 + title: "",
  364 + // 部门树选项
  365 + deptOptions: undefined,
  366 + // 是否显示弹出层
  367 + open: false,
  368 + // 部门名称
  369 + deptName: undefined,
  370 + // 默认密码
  371 + initPassword: undefined,
  372 + // 日期范围
  373 + dateRange: [],
  374 + // 状态数据字典
  375 + statusOptions: [],
  376 + // 性别状态字典
  377 + sexOptions: [],
  378 + // 岗位选项
  379 + postOptions: [],
  380 + // 角色选项
  381 + roleOptions: [],
  382 + // 表单参数
  383 + form: {},
  384 + defaultProps: {
  385 + children: "children",
  386 + label: "name"
  387 + },
  388 + // 用户导入参数
  389 + upload: {
  390 + // 是否显示弹出层(用户导入)
  391 + open: false,
  392 + // 弹出层标题(用户导入)
  393 + title: "",
  394 + // 是否禁用上传
  395 + isUploading: false,
  396 + // 是否更新已经存在的用户数据
  397 + updateSupport: 0,
  398 + // 设置上传的请求头部
  399 + headers: { Authorization: "Bearer " + getToken() },
  400 + // 上传的地址
  401 + url: process.env.VUE_APP_BASE_API + '/api/' + "/system/user/import"
  402 + },
  403 + // 查询参数
  404 + queryParams: {
  405 + pageNo: 1,
  406 + pageSize: 10,
  407 + username: undefined,
  408 + mobile: undefined,
  409 + status: undefined,
  410 + deptId: undefined
  411 + },
  412 + // 表单校验
  413 + rules: {
  414 + username: [
  415 + { required: true, message: "用户名称不能为空", trigger: "blur" }
  416 + ],
  417 + nickname: [
  418 + { required: true, message: "用户昵称不能为空", trigger: "blur" }
  419 + ],
  420 + password: [
  421 + { required: true, message: "用户密码不能为空", trigger: "blur" }
  422 + ],
  423 + email: [
  424 + {
  425 + type: "email",
  426 + message: "'请输入正确的邮箱地址",
  427 + trigger: ["blur", "change"]
  428 + }
  429 + ],
  430 + mobile: [
  431 + {
  432 + pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
  433 + message: "请输入正确的手机号码",
  434 + trigger: "blur"
  435 + }
  436 + ]
  437 + },
  438 + // 是否显示弹出层(角色权限)
  439 + openRole: false,
  440 +
  441 + // 枚举
  442 + SysCommonStatusEnum: SysCommonStatusEnum,
  443 + // 数据字典
  444 + statusDictDatas: getDictDatas(DICT_TYPE.SYS_COMMON_STATUS),
  445 + sexDictDatas: getDictDatas(DICT_TYPE.SYS_USER_SEX),
  446 + };
  447 + },
  448 + watch: {
  449 + // 根据名称筛选部门树
  450 + deptName(val) {
  451 + this.$refs.tree.filter(val);
  452 + }
  453 + },
  454 + created() {
  455 + this.getList();
  456 + this.getTreeselect();
  457 + this.getConfigKey("sys.user.initPassword").then(response => {
  458 + this.initPassword = response.msg;
  459 + });
  460 + },
  461 + methods: {
  462 + // 更多操作
  463 + handleCommand(command, index, row) {
  464 + switch (command) {
  465 + case 'handleUpdate':
  466 + this.handleUpdate(row);//修改客户信息
  467 + break;
  468 + case 'handleDelete':
  469 + this.handleDelete(row);//红号变更
  470 + break;
  471 + case 'handleResetPwd':
  472 + this.handleResetPwd(row);
  473 + break;
  474 + case 'handleRole':
  475 + this.handleRole(row);
  476 + break;
  477 + default:
  478 + break;
  479 + }
  480 + },
  481 + /** 查询用户列表 */
  482 + getList() {
  483 + this.loading = true;
  484 + listUser(this.addDateRange(this.queryParams, [
  485 + this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined,
  486 + this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined,
  487 + ])).then(response => {
  488 + this.userList = response.data.list;
  489 + this.total = response.data.total;
  490 + this.loading = false;
  491 + }
  492 + );
  493 + },
  494 + /** 查询部门下拉树结构 + 岗位下拉 */
  495 + getTreeselect() {
  496 + listSimpleDepts().then(response => {
  497 + // 处理 deptOptions 参数
  498 + this.deptOptions = [];
  499 + this.deptOptions.push(...this.handleTree(response.data, "id"));
  500 + });
  501 + listSimplePosts().then(response => {
  502 + // 处理 postOptions 参数
  503 + this.postOptions = [];
  504 + this.postOptions.push(...response.data);
  505 + });
  506 + },
  507 + // 筛选节点
  508 + filterNode(value, data) {
  509 + if (!value) return true;
  510 + return data.name.indexOf(value) !== -1;
  511 + },
  512 + // 节点单击事件
  513 + handleNodeClick(data) {
  514 + this.queryParams.deptId = data.id;
  515 + this.getList();
  516 + },
  517 + // 用户状态修改
  518 + handleStatusChange(row) {
  519 + let text = row.status === SysCommonStatusEnum.ENABLE ? "启用" : "停用";
  520 + this.$confirm('确认要"' + text + '""' + row.username + '"用户吗?', "警告", {
  521 + confirmButtonText: "确定",
  522 + cancelButtonText: "取消",
  523 + type: "warning"
  524 + }).then(function() {
  525 + return changeUserStatus(row.id, row.status);
  526 + }).then(() => {
  527 + this.msgSuccess(text + "成功");
  528 + }).catch(function() {
  529 + row.status = row.status === SysCommonStatusEnum.ENABLE ? SysCommonStatusEnum.DISABLE
  530 + : SysCommonStatusEnum.ENABLE;
  531 + });
  532 + },
  533 + // 取消按钮
  534 + cancel() {
  535 + this.open = false;
  536 + this.reset();
  537 + },
  538 + // 取消按钮(角色权限)
  539 + cancelRole() {
  540 + this.openRole = false;
  541 + this.reset();
  542 + },
  543 + // 表单重置
  544 + reset() {
  545 + this.form = {
  546 + id: undefined,
  547 + deptId: undefined,
  548 + username: undefined,
  549 + nickname: undefined,
  550 + password: undefined,
  551 + mobile: undefined,
  552 + email: undefined,
  553 + sex: undefined,
  554 + status: "0",
  555 + remark: undefined,
  556 + postIds: [],
  557 + roleIds: []
  558 + };
  559 + this.resetForm("form");
  560 + },
  561 + /** 搜索按钮操作 */
  562 + handleQuery() {
  563 + this.queryParams.pageNo = 1;
  564 + this.getList();
  565 + },
  566 + /** 重置按钮操作 */
  567 + resetQuery() {
  568 + this.dateRange = [];
  569 + this.resetForm("queryForm");
  570 + this.handleQuery();
  571 + },
  572 + /** 新增按钮操作 */
  573 + handleAdd() {
  574 + this.reset();
  575 + // 获得下拉数据
  576 + this.getTreeselect();
  577 + // 打开表单,并设置初始化
  578 + this.open = true;
  579 + this.title = "添加用户";
  580 + this.form.password = this.initPassword;
  581 + },
  582 + /** 修改按钮操作 */
  583 + handleUpdate(row) {
  584 + this.reset();
  585 + this.getTreeselect();
  586 + const id = row.id;
  587 + getUser(id).then(response => {
  588 + this.form = response.data;
  589 + this.open = true;
  590 + this.title = "修改用户";
  591 + this.form.password = "";
  592 + });
  593 + },
  594 + /** 重置密码按钮操作 */
  595 + handleResetPwd(row) {
  596 + this.$prompt('请输入"' + row.username + '"的新密码', "提示", {
  597 + confirmButtonText: "确定",
  598 + cancelButtonText: "取消"
  599 + }).then(({ value }) => {
  600 + resetUserPwd(row.id, value).then(response => {
  601 + this.msgSuccess("修改成功,新密码是:" + value);
  602 + });
  603 + }).catch(() => {});
  604 + },
  605 + /** 分配用户角色操作 */
  606 + handleRole(row) {
  607 + this.reset();
  608 + const id = row.id
  609 + // 处理了 form 的用户 username 和 nickname 的展示
  610 + this.form.id = id;
  611 + this.form.username = row.username;
  612 + this.form.nickname = row.nickname;
  613 + // 打开弹窗
  614 + this.openRole = true;
  615 + // 获得角色列表
  616 + listSimpleRoles().then(response => {
  617 + // 处理 roleOptions 参数
  618 + this.roleOptions = [];
  619 + this.roleOptions.push(...response.data);
  620 + });
  621 + // 获得角色拥有的菜单集合
  622 + listUserRoles(id).then(response => {
  623 + // 设置选中
  624 + this.form.roleIds = response.data;
  625 + })
  626 + },
  627 + /** 提交按钮 */
  628 + submitForm: function() {
  629 + this.$refs["form"].validate(valid => {
  630 + if (valid) {
  631 + if (this.form.id !== undefined) {
  632 + updateUser(this.form).then(response => {
  633 + this.msgSuccess("修改成功");
  634 + this.open = false;
  635 + this.getList();
  636 + });
  637 + } else {
  638 + addUser(this.form).then(response => {
  639 + this.msgSuccess("新增成功");
  640 + this.open = false;
  641 + this.getList();
  642 + });
  643 + }
  644 + }
  645 + });
  646 + },
  647 + /** 提交按钮(角色权限) */
  648 + submitRole: function() {
  649 + if (this.form.id !== undefined) {
  650 + assignUserRole({
  651 + userId: this.form.id,
  652 + roleIds: this.form.roleIds,
  653 + }).then(response => {
  654 + this.msgSuccess("分配角色成功");
  655 + this.openRole = false;
  656 + this.getList();
  657 + });
  658 + }
  659 + },
  660 + /** 删除按钮操作 */
  661 + handleDelete(row) {
  662 + const ids = row.id || this.ids;
  663 + this.$confirm('是否确认删除用户编号为"' + ids + '"的数据项?', "警告", {
  664 + confirmButtonText: "确定",
  665 + cancelButtonText: "取消",
  666 + type: "warning"
  667 + }).then(function() {
  668 + return delUser(ids);
  669 + }).then(() => {
  670 + this.getList();
  671 + this.msgSuccess("删除成功");
  672 + })
  673 + },
  674 + /** 导出按钮操作 */
  675 + handleExport() {
  676 + const queryParams = this.addDateRange(this.queryParams, [
  677 + this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined,
  678 + this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined,
  679 + ]);
  680 + this.$confirm('是否确认导出所有用户数据项?', "警告", {
  681 + confirmButtonText: "确定",
  682 + cancelButtonText: "取消",
  683 + type: "warning"
  684 + }).then(function() {
  685 + return exportUser(queryParams);
  686 + }).then(response => {
  687 + this.downloadExcel(response, '用户数据.xls');
  688 + })
  689 + },
  690 + /** 导入按钮操作 */
  691 + handleImport() {
  692 + this.upload.title = "用户导入";
  693 + this.upload.open = true;
  694 + },
  695 + /** 下载模板操作 */
  696 + importTemplate() {
  697 + importTemplate().then(response => {
  698 + this.downloadExcel(response, '用户导入模板.xls');
  699 + });
  700 + },
  701 + // 文件上传中处理
  702 + handleFileUploadProgress(event, file, fileList) {
  703 + this.upload.isUploading = true;
  704 + },
  705 + // 文件上传成功处理
  706 + handleFileSuccess(response, file, fileList) {
  707 + this.upload.open = false;
  708 + this.upload.isUploading = false;
  709 + this.$refs.upload.clearFiles();
  710 + // 拼接提示语
  711 + let data = response.data;
  712 + let text = '创建成功数量:' + data.createUsernames.length;
  713 + for (const username of data.createUsernames) {
  714 + text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username;
  715 + }
  716 + text += '<br />更新成功数量:' + data.updateUsernames.length;
  717 + for (const username of data.updateUsernames) {
  718 + text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username;
  719 + }
  720 + text += '<br />更新失败数量:' + Object.keys(data.failureUsernames).length;
  721 + for (const username in data.failureUsernames) {
  722 + text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username + ':' + data.failureUsernames[username];
  723 + }
  724 + this.$alert(text, "导入结果", { dangerouslyUseHTMLString: true });
  725 + this.getList();
  726 + },
  727 + // 提交上传文件
  728 + submitFileForm() {
  729 + this.$refs.upload.submit();
  730 + },
  731 + // 格式化部门的下拉框
  732 + normalizer(node) {
  733 + return {
  734 + id: node.id,
  735 + label: node.name,
  736 + children: node.children
  737 + }
  738 + }
  739 + }
  740 +};
  741 +</script>
  742 +<style>
  743 + .el-dropdown-link {
  744 + cursor: pointer;
  745 + color: #1890ff;
  746 + margin-left: 5px;
  747 + }
  748 + .el-icon-arrow-down {
  749 + font-size: 14px;
  750 + }
  751 +</style>