<template>
	<div class="user-container">
		<!-- <doc-alert title="用户体系" url="https://doc.iocoder.cn/user-center/" />
    <doc-alert title="三方登陆" url="https://doc.iocoder.cn/social-user/" />
    <doc-alert
      title="Excel 导入导出"
      url="https://doc.iocoder.cn/excel-import-and-export/"
    /> -->
		<!-- 搜索工作栏 -->

		<el-row :gutter="8" class="user-box">
			<!--部门数据-->
			<el-col :span="4" :xs="24">
				<div class="user-box-left">
					<div class="head-container">
						<el-input
							v-model="deptName"
							placeholder="请输入部门名称"
							clearable
							size="small"
							prefix-icon="el-icon-search"
							style="margin-bottom: 20px" />
					</div>
					<div class="head-container">
						<el-tree
							:data="deptOptions"
							:props="defaultProps"
							:expand-on-click-node="false"
							:filter-node-method="filterNode"
							ref="tree"
							default-expand-all
							highlight-current
							@node-click="handleNodeClick" />
					</div>
				</div>
			</el-col>
			<!--用户数据-->
			<el-col :span="20" :xs="24">
				<div class="user-box-right">
					<search-bar
						:formConfigs="formConfig"
						ref="userSearchBarForm"
						@headBtnClick="buttonClick" />
					<!-- 列表 -->
					<base-table
						:page="queryParams.pageNo"
						:limit="queryParams.pageSize"
						:table-props="tableProps"
						:table-data="userList"
						:max-height="tableH"
						@emitFun="handleStatusChange">
						<method-btn
							v-if="tableBtn.length"
							slot="handleBtn"
							:width="220"
							label="操作"
							:method-list="tableBtn"
							@clickBtn="handleClick" />
					</base-table>

					<pagination
						:page.sync="queryParams.pageNo"
						:limit.sync="queryParams.pageSize"
						:total="total"
						@pagination="getList" />
				</div>
			</el-col>
		</el-row>

		<!-- 添加或修改参数配置对话框 -->
		<base-dialog :dialogTitle="title" :dialogVisible="open" width="50%">
			<el-form ref="form" :model="form" :rules="rules" label-width="100px">
				<el-row>
					<el-col :span="12">
						<el-form-item label="用户昵称" prop="nickname">
							<el-input v-model="form.nickname" placeholder="请输入用户昵称" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="归属部门" prop="deptId">
							<treeselect
								v-model="form.deptId"
								:options="deptOptions"
								:show-count="true"
								:clearable="false"
								placeholder="请选择归属部门"
								:normalizer="normalizer" />
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="手机号码" prop="mobile">
							<el-input
								v-model="form.mobile"
								placeholder="请输入手机号码"
								maxlength="11" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="邮箱" prop="email">
							<el-input
								v-model="form.email"
								placeholder="请输入邮箱"
								maxlength="50" />
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item
							v-if="form.id === undefined"
							label="用户名称"
							prop="username">
							<el-input v-model="form.username" placeholder="请输入用户名称" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item
							v-if="form.id === undefined"
							label="用户密码"
							prop="password">
							<el-input
								v-model="form.password"
								placeholder="请输入用户密码"
								type="password"
								show-password />
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="用户性别">
							<el-select
								v-model="form.sex"
								placeholder="请选择"
								style="width: 100%">
								<el-option
									v-for="dict in sexDictDatas"
									:key="parseInt(dict.value)"
									:label="dict.label"
									:value="parseInt(dict.value)" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="岗位">
							<el-select
								v-model="form.postIds"
								multiple
								placeholder="请选择"
								style="width: 100%">
								<el-option
									v-for="item in postOptions"
									:key="item.id"
									:label="item.name"
									:value="item.id"></el-option>
							</el-select>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="24">
						<el-form-item label="备注">
							<el-input
								v-model="form.remark"
								type="textarea"
								placeholder="请输入内容"></el-input>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="cancel">取 消</el-button>
				<el-button type="primary" @click="submitForm">确 定</el-button>
			</div>
		</base-dialog>

		<!-- 用户导入对话框 -->
		<base-dialog
			:dialogTitle="upload.title"
			:dialogVisible="upload.open"
			width="400px">
			<el-upload
				ref="upload"
				:limit="1"
				accept=".xlsx, .xls"
				:headers="upload.headers"
				:action="upload.url + '?updateSupport=' + upload.updateSupport"
				:disabled="upload.isUploading"
				:on-progress="handleFileUploadProgress"
				:on-success="handleFileSuccess"
				:auto-upload="false"
				drag>
				<i class="el-icon-upload"></i>
				<div class="el-upload__text">
					将文件拖到此处,或
					<em>点击上传</em>
				</div>
				<div class="el-upload__tip text-center" slot="tip">
					<div class="el-upload__tip" slot="tip">
						<el-checkbox v-model="upload.updateSupport" />
						是否更新已经存在的用户数据
					</div>
					<span>仅允许导入xls、xlsx格式文件。</span>
					<el-link
						type="primary"
						:underline="false"
						style="font-size: 12px; vertical-align: baseline"
						@click="importTemplate">
						导出模板
					</el-link>
				</div>
			</el-upload>
			<div slot="footer" class="dialog-footer">
				<el-button type="primary" @click="submitFileForm">确 定</el-button>
				<el-button @click="upload.open = false">取 消</el-button>
			</div>
		</base-dialog>

		<!-- 分配角色 -->
		<base-dialog dialogTitle="分配角色" :dialogVisible="openRole" width="500px">
			<el-form :model="form" label-width="80px">
				<el-form-item label="用户名称">
					<el-input v-model="form.username" :disabled="true" />
				</el-form-item>
				<el-form-item label="用户昵称">
					<el-input v-model="form.nickname" :disabled="true" />
				</el-form-item>
				<el-form-item label="角色">
					<el-select
						v-model="form.roleIds"
						multiple
						placeholder="请选择"
						style="width: 100%">
						<el-option
							v-for="item in roleOptions"
							:key="parseInt(item.id)"
							:label="item.name"
							:value="parseInt(item.id)"></el-option>
					</el-select>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="cancelRole">取 消</el-button>
				<el-button type="primary" @click="submitRole">确 定</el-button>
			</div>
		</base-dialog>
	</div>
</template>

<script>
import {
	addUser,
	changeUserStatus,
	delUser,
	exportUser,
	getUser,
	importTemplate,
	listUser,
	resetUserPwd,
	updateUser,
} from '@/api/system/user';
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';

import { listSimpleDepts } from '@/api/system/dept';
import { listSimplePosts } from '@/api/system/post';

import { CommonStatusEnum } from '@/utils/constants';
import { DICT_TYPE, getDictDatas } from '@/utils/dict';
import { assignUserRole, listUserRoles } from '@/api/system/permission';
import { listSimpleRoles } from '@/api/system/role';
import { getBaseHeader } from '@/utils/request';
import tableHeightMixin from '@/mixins/tableHeightMixin';
import { parseTime } from '@/utils/ruoyi';
import statusBtn5 from './../components/statusBtn5.vue';
const tableProps = [
	{
		prop: 'id',
		label: '用户编号',
		showOverflowtooltip: true,
	},
	{
		prop: 'username',
		label: '用户名称',
		minWidth: 120,
		showOverflowtooltip: true,
	},
	{
		prop: 'nickname',
		label: '用户昵称',
		minWidth: 120,
		showOverflowtooltip: true,
	},
	{
		prop: 'dept',
		label: '部门',
		minWidth: 120,
		filter: (item) => item?.name || '',
		showOverflowtooltip: true,
	},
	{
		prop: 'mobile',
		label: '手机号码',
		minWidth: 150,
		showOverflowtooltip: true,
	},
	{
		prop: 'status',
		label: '状态',
		minWidth: 80,
		// filter: publicFormatter(DICT_TYPE.SYSTEM_OPERATE_TYPE),
		subcomponent: statusBtn5,
	},
	{
		prop: 'createTime',
		label: '创建时间',
		filter: parseTime,
		minWidth: 150,
		showOverflowtooltip: true,
	},
];
export default {
	name: 'SystemUser',
	mixins: [tableHeightMixin],
	components: { Treeselect },
	data() {
		return {
			formConfig: [
				{
					type: 'input',
					label: '用户名称',
					placeholder: '用户名称',
					param: 'username',
					width: 150,
				},
				{
					type: 'input',
					label: '手机号码',
					placeholder: '手机号码',
					param: 'mobile',
					width: 150,
				},
				{
					type: 'select',
					label: '状态',
					selectOptions: this.getDictDatas(this.DICT_TYPE.COMMON_STATUS),
					labelField: 'label',
					valueField: 'value',
					param: 'status',
					width: 100,
				},
				{
					type: 'datePicker',
					label: '创建时间',
					dateType: 'daterange',
					format: 'yyyy-MM-dd',
					valueFormat: 'yyyy-MM-dd HH:mm:ss',
					rangeSeparator: '-',
					startPlaceholder: '开始日期',
					endPlaceholder: '结束日期',
					param: 'createTime',
					defaultSelect: [],
					defaultTime: ['00:00:00', '23:59:59'],
					width: 250,
				},
				{
					type: 'button',
					btnName: '查询',
					name: 'search',
					color: 'primary',
				},
				{
					type: 'button',
					btnName: '重置',
					name: 'cancel',
				},
				{
					type: this.$auth.hasPermiOr([
						'system:user:create',
						'system:user:import',
						'system:user:export',
					])
						? 'separate'
						: '',
				},
				{
					type: this.$auth.hasPermi('system:user:import') ? 'button' : '',
					btnName: '导入',
					name: 'import',
					color: 'primary',
					plain: true,
				},
				{
					type: this.$auth.hasPermi('system:user:export') ? 'button' : '',
					btnName: '导出',
					name: 'export',
					color: 'primary',
					plain: true,
				},
				{
					type: this.$auth.hasPermi('system:user:create') ? 'button' : '',
					btnName: '新增',
					name: 'addNew',
					color: 'success',
					plain: true,
				},
			],
			tableBtn: [
				this.$auth.hasPermi('system:user:update-password')
					? {
							type: 'reset',
							btnName: '重置密码',
					  }
					: undefined,
				this.$auth.hasPermi('system:permission:assign-user-role')
					? {
							type: 'role',
							btnName: '分配角色',
					  }
					: undefined,
				this.$auth.hasPermi('system:user:update')
					? {
							type: 'edit',
							btnName: '修改',
					  }
					: undefined,
				this.$auth.hasPermi('system:user:delete')
					? {
							type: 'delete',
							btnName: '删除',
					  }
					: undefined,
			].filter((v) => v),
			tableProps,
			// 遮罩层
			loading: true,
			// 导出遮罩层
			exportLoading: false,
			// 显示搜索条件
			showSearch: true,
			// 总条数
			total: 0,
			// 用户表格数据
			userList: [],
			// 弹出层标题
			title: '',
			// 部门树选项
			deptOptions: undefined,
			// 是否显示弹出层
			open: false,
			// 部门名称
			deptName: undefined,
			// 默认密码
			initPassword: undefined,
			// 性别状态字典
			sexOptions: [],
			// 岗位选项
			postOptions: [],
			// 角色选项
			roleOptions: [],
			// 表单参数
			form: {},
			defaultProps: {
				children: 'children',
				label: 'name',
			},
			// 用户导入参数
			upload: {
				// 是否显示弹出层(用户导入)
				open: false,
				// 弹出层标题(用户导入)
				title: '',
				// 是否禁用上传
				isUploading: false,
				// 是否更新已经存在的用户数据
				updateSupport: 0,
				// 设置上传的请求头部
				headers: getBaseHeader(),
				// 上传的地址
				url: process.env.VUE_APP_BASE_API + '/admin-api/system/user/import',
			},
			// 查询参数
			queryParams: {
				pageNo: 1,
				pageSize: 20,
				username: undefined,
				mobile: undefined,
				status: undefined,
				deptId: undefined,
				createTime: [],
			},
			// 表单校验
			rules: {
				username: [
					{ required: true, message: '用户名称不能为空', trigger: 'blur' },
				],
				deptId: [
					{ required: true, message: '归属部门不能为空', trigger: 'change' },
				],
				nickname: [
					{ required: true, message: '用户昵称不能为空', trigger: 'blur' },
				],
				password: [
					{ required: true, message: '用户密码不能为空', trigger: 'blur' },
				],
				email: [
					{
						type: 'email',
						message: "'请输入正确的邮箱地址",
						trigger: ['blur', 'change'],
					},
				],
				mobile: [
					{
						pattern:
							/^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/,
						message: '请输入正确的手机号码',
						trigger: 'blur',
					},
				],
			},
			// 是否显示弹出层(角色权限)
			openRole: false,

			// 枚举
			SysCommonStatusEnum: CommonStatusEnum,
			// 数据字典
			statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS),
			sexDictDatas: getDictDatas(DICT_TYPE.SYSTEM_USER_SEX),
		};
	},
	watch: {
		// 根据名称筛选部门树
		deptName(val) {
			this.$refs.tree.filter(val);
		},
	},
	created() {
		this.getList();
		this.getTreeselect();
		// this.getConfigKey("sys.user.init-password").then(response => {
		//   this.initPassword = response.msg;
		// });
	},
	methods: {
		handleClick(val) {
			switch (val.type) {
				case 'edit':
					this.handleUpdate(val.data);
					break;
				case 'delete':
					this.handleDelete(val.data.id, val.data.username);
					break;
				case 'reset':
					this.handleResetPwd(val.data);
					break;
				default:
					this.handleRole(val.data);
			}
		},
		buttonClick(val) {
			console.log(val);
			switch (val.btnName) {
				case 'search':
					this.handleQuery(val);
					break;
				case 'cancel':
					this.$refs['userSearchBarForm'].resetForm();
					this.queryParams.pageNo = 1;
					this.queryParams.username = '';
					this.queryParams.mobile = '';
					this.queryParams.status = '';
					this.queryParams.createTime = [];
					this.getList();
					break;
				case 'addNew':
					this.handleAdd();
					break;
				case 'import':
					this.handleImport();
					break;
				default:
					this.handleExport();
			}
		},
		/** 查询用户列表 */
		getList() {
			this.loading = true;
			listUser(this.queryParams).then((response) => {
				this.userList = response.data.list;
				this.total = response.data.total;
				this.loading = false;
			});
		},
		/** 查询部门下拉树结构 + 岗位下拉 */
		getTreeselect() {
			listSimpleDepts().then((response) => {
				// 处理 deptOptions 参数
				this.deptOptions = [];
				this.deptOptions.push(...this.handleTree(response.data, 'id'));
			});
			listSimplePosts().then((response) => {
				// 处理 postOptions 参数
				this.postOptions = [];
				this.postOptions.push(...response.data);
			});
		},
		// 筛选节点
		filterNode(value, data) {
			if (!value) return true;
			return data.name.indexOf(value) !== -1;
		},
		// 节点单击事件
		handleNodeClick(data) {
			this.queryParams.deptId = data.id;
			this.getList();
		},
		// 用户状态修改
		handleStatusChange(row) {
			changeUserStatus(row.id, row.status).then((res) => {
				this.$modal.msgSuccess('操作成功');
			});
		},
		// 取消按钮
		cancel() {
			this.open = false;
			this.reset();
		},
		// 取消按钮(角色权限)
		cancelRole() {
			this.openRole = false;
			this.reset();
		},
		// 表单重置
		reset() {
			this.form = {
				id: undefined,
				deptId: undefined,
				username: undefined,
				nickname: undefined,
				password: undefined,
				mobile: undefined,
				email: undefined,
				sex: undefined,
				status: '0',
				remark: undefined,
				postIds: [],
				roleIds: [],
			};
			this.resetForm('form');
		},
		/** 搜索按钮操作 */
		handleQuery(val) {
			this.queryParams.pageNo = 1;
			this.queryParams.username = val.username;
			this.queryParams.mobile = val.mobile;
			this.queryParams.status = val.status;
			this.queryParams.createTime = val.createTime;
			this.getList();
		},
		/** 新增按钮操作 */
		handleAdd() {
			this.reset();
			// 获得下拉数据
			this.getTreeselect();
			// 打开表单,并设置初始化
			this.open = true;
			this.title = '添加用户';
			this.form.password = this.initPassword;
		},
		/** 修改按钮操作 */
		handleUpdate(row) {
			this.reset();
			this.getTreeselect();
			const id = row.id;
			getUser(id).then((response) => {
				this.form = response.data;
				this.open = true;
				this.title = '修改用户';
			});
		},
		/** 重置密码按钮操作 */
		handleResetPwd(row) {
			this.$modal
				.prompt('请输入 【' + row.username + '】 的新密码')
				.then(({ value }) => {
					resetUserPwd(row.id, value).then((response) => {
						this.$modal.msgSuccess('修改成功,新密码是:' + value);
					});
				})
				.catch(() => {});
		},
		/** 分配用户角色操作 */
		handleRole(row) {
			this.reset();
			const id = row.id;
			// 处理了 form 的用户 username 和 nickname 的展示
			this.form.id = id;
			this.form.username = row.username;
			this.form.nickname = row.nickname;
			// 打开弹窗
			this.openRole = true;
			// 获得角色列表
			listSimpleRoles().then((response) => {
				// 处理 roleOptions 参数
				this.roleOptions = [];
				this.roleOptions.push(...response.data);
			});
			// 获得角色拥有的菜单集合
			listUserRoles(id).then((response) => {
				// 设置选中
				this.form.roleIds = response.data;
			});
		},
		/** 提交按钮 */
		submitForm: function () {
			this.$refs['form'].validate((valid) => {
				if (valid) {
					if (this.form.id !== undefined) {
						updateUser(this.form).then((response) => {
							this.$modal.msgSuccess('修改成功');
							this.open = false;
							this.getList();
						});
					} else {
						addUser(this.form).then((response) => {
							this.$modal.msgSuccess('新增成功');
							this.open = false;
							this.getList();
						});
					}
				}
			});
		},
		/** 提交按钮(角色权限) */
		submitRole: function () {
			if (this.form.id !== undefined) {
				assignUserRole({
					userId: this.form.id,
					roleIds: this.form.roleIds,
				}).then((response) => {
					this.$modal.msgSuccess('分配角色成功');
					this.openRole = false;
					this.getList();
				});
			}
		},
		/** 删除按钮操作 */
		handleDelete(id, detContent) {
			this.$modal
				.delConfirm(detContent)
				.then(() => {
					return delUser(id);
				})
				.then(() => {
					this.getList();
					this.$modal.msgSuccess('删除成功');
				})
				.catch(() => {});
		},
		/** 导出按钮操作 */
		handleExport() {
			this.$modal
				.confirm('是否确认导出所有用户数据项?')
				.then(() => {
					// 处理查询参数
					let params = { ...this.queryParams };
					params.pageNo = undefined;
					params.pageSize = undefined;
					this.exportLoading = true;
					return exportUser(params);
				})
				.then((response) => {
					this.$download.excel(response, '用户数据.xls');
					this.exportLoading = false;
				})
				.catch(() => {});
		},
		/** 导入按钮操作 */
		handleImport() {
			this.upload.title = '用户导入';
			this.upload.open = true;
		},
		/** 导出模板操作 */
		importTemplate() {
			importTemplate().then((response) => {
				this.$download.excel(response, '用户导入模板.xls');
			});
		},
		// 文件上传中处理
		handleFileUploadProgress(event, file, fileList) {
			this.upload.isUploading = true;
		},
		// 文件上传成功处理
		handleFileSuccess(response, file, fileList) {
			if (response.code !== 0) {
				this.$modal.msgError(response.msg);
				return;
			}
			this.upload.open = false;
			this.upload.isUploading = false;
			this.$refs.upload.clearFiles();
			// 拼接提示语
			let data = response.data;
			let text = '创建成功数量:' + data.createUsernames.length;
			for (const username of data.createUsernames) {
				text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username;
			}
			text += '<br />更新成功数量:' + data.updateUsernames.length;
			for (const username of data.updateUsernames) {
				text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username;
			}
			text +=
				'<br />更新失败数量:' + Object.keys(data.failureUsernames).length;
			for (const username in data.failureUsernames) {
				text +=
					'<br />&nbsp;&nbsp;&nbsp;&nbsp;' +
					username +
					':' +
					data.failureUsernames[username];
			}
			this.$alert(text, '导入结果', { dangerouslyUseHTMLString: true });
			this.getList();
		},
		// 提交上传文件
		submitFileForm() {
			this.$refs.upload.submit();
		},
		// 格式化部门的下拉框
		normalizer(node) {
			return {
				id: node.id,
				label: node.name,
				children: node.children,
			};
		},
	},
};
</script>
<style lang="scss" scoped>
.user-container {
	width: 100%;
	height: calc(100vh - 164px);
	background-color: #f2f4f9;

	.user-box {
		.user-box-left,
		.user-box-right {
			background-color: #fff;
			padding: 8px;
			border-radius: 8px;
			height: calc(100vh - 164px);
		}
	}
}
</style>