diff --git a/src/api/sys/model/userModel.ts b/src/api/sys/model/userModel.ts index ce0e2819..cae50324 100644 --- a/src/api/sys/model/userModel.ts +++ b/src/api/sys/model/userModel.ts @@ -27,7 +27,7 @@ export interface GetUserInfoModel { // 名称 name: string // 账号 - username: string + account: string // 头像 avatar: string } diff --git a/src/api/sys/userAssist.ts b/src/api/sys/userAssist.ts new file mode 100644 index 00000000..a74c2508 --- /dev/null +++ b/src/api/sys/userAssist.ts @@ -0,0 +1,50 @@ +import { defHttp } from '@/utils/http/axios' +import { Result } from '#/axios' + +/** + * 账号是否被使用 + */ +export function existsAccount(account) { + return defHttp.get>({ + url: `/user/existsAccount`, + params: { account }, + }) +} +export function existsAccountNotId(account, id) { + return defHttp.get>({ + url: `/user/existsAccountNotId`, + params: { account, id }, + }) +} + +/** + * 手机号是否被使用 + */ +export function existsPhone(phone) { + return defHttp.get>({ + url: `/user/existsPhone`, + params: { phone }, + }) +} +export function existsPhoneNotId(phone, id) { + return defHttp.get>({ + url: `/user/existsPhoneNotId`, + params: { phone, id }, + }) +} + +/** + * 邮箱是否被使用 + */ +export function existsEmail(email) { + return defHttp.get>({ + url: `/user/existsEmail`, + params: { email }, + }) +} +export function existsEmailNotId(email, id) { + return defHttp.get>({ + url: `/user/existsEmailNotId`, + params: { email, id }, + }) +} diff --git a/src/utils/validate.ts b/src/utils/validate.ts new file mode 100644 index 00000000..414371b3 --- /dev/null +++ b/src/utils/validate.ts @@ -0,0 +1,254 @@ +/** + * 邮箱 + * @param {*} s + */ +export function isEmail(s) { + return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s) +} + +/** + * 手机号码 + * @param {*} s + */ +export function isMobile(s) { + return /^1[0-9]{10}$/.test(s) +} + +/** + * 电话号码 + * @param {*} s + */ +export function isPhone(s) { + return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s) +} + +/** + * URL地址 + * @param {*} s + */ +export function isURL(s) { + return /^http[s]?:\/\/.*/.test(s) +} + +export function isValidUsername(str) { + const validMap = ['admin', 'editor'] + return validMap.indexOf(str.trim()) >= 0 +} + +/* 合法uri */ +export function validateURL(textval) { + const urlregex = + /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + return urlregex.test(textval) +} + +/* 小写字母 */ +export function validateLowerCase(str) { + const reg = /^[a-z]+$/ + return reg.test(str) +} + +/* 大写字母 */ +export function validateUpperCase(str) { + const reg = /^[A-Z]+$/ + return reg.test(str) +} + +/* 大小写字母 */ +export function validateAlphabets(str) { + const reg = /^[A-Za-z]+$/ + return reg.test(str) +} + +/* 验证pad还是pc */ +export const validatePc = function () { + const userAgentInfo = navigator.userAgent + const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'] + let flag = true + for (let v = 0; v < Agents.length; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = false + break + } + } + return flag +} + +/** + * 判断身份证号码 + */ +export function validateCardId(code) { + let result = true + let msg = '' + const city = { + 11: '北京', + 12: '天津', + 13: '河北', + 14: '山西', + 15: '内蒙古', + 21: '辽宁', + 22: '吉林', + 23: '黑龙江 ', + 31: '上海', + 32: '江苏', + 33: '浙江', + 34: '安徽', + 35: '福建', + 36: '江西', + 37: '山东', + 41: '河南', + 42: '湖北 ', + 43: '湖南', + 44: '广东', + 45: '广西', + 46: '海南', + 50: '重庆', + 51: '四川', + 52: '贵州', + 53: '云南', + 54: '西藏 ', + 61: '陕西', + 62: '甘肃', + 63: '青海', + 64: '宁夏', + 65: '新疆', + 71: '台湾', + 81: '香港', + 82: '澳门', + 91: '国外 ', + } + if (!validateNull(code)) { + if (code.length === 18) { + if (!code || !/(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(code)) { + msg = '证件号码格式错误' + } else if (!city[code.substr(0, 2)]) { + msg = '地址编码错误' + } else { + // 18位身份证需要验证最后一位校验位 + code = code.split('') + // ∑(ai×Wi)(mod 11) + // 加权因子 + const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] + // 校验位 + const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2, 'x'] + let sum = 0 + let ai = 0 + let wi = 0 + for (let i = 0; i < 17; i++) { + ai = code[i] + wi = factor[i] + sum += ai * wi + } + if (parity[sum % 11] !== code[17]) { + msg = '证件号码校验位错误' + } else { + result = false + } + } + } else { + msg = '证件号码长度不为18位' + } + } else { + msg = '证件号码不能为空' + } + return { result, msg } +} + +/** + * 邮件 + */ +export function validateEmail(email) { + const isEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/ + let result = false + let msg = '' + if (!validateNull(email)) { + if (!isEmail.test(email)) { + msg = '邮箱格式不正确' + } else { + result = true + } + } else { + msg = '邮箱不能为空' + } + return { result, msg } +} + +/** + * 判断手机号码是否正确 + * @return + */ +export function validateMobile(phone) { + let result = false + let msg = '' + const isPhone = /^(1[0-9])\d{9}$/ + if (!validateNull(phone)) { + if (phone.length === 11) { + if (!isPhone.test(phone)) { + msg = '手机号码格式不正确' + } else { + result = true + } + } else { + msg = '手机号码格式不正确' + } + } else { + msg = '手机号码不能为空' + } + return { result, msg } +} + +/** + * 判断姓名是否正确 + */ +export function validateName(name) { + const regName = /^[\u4e00-\u9fa5]{2,4}$/ + return regName.test(name) +} + +/** + * 判断是否为整数 + */ +export function validateNum(num, type) { + let regName = /[^\d.]/g + if (type === 1) { + if (!regName.test(num)) return false + } else if (type === 2) { + regName = /[^\d]/g + if (!regName.test(num)) return false + } + return true +} + +/** + * 判断是否为小数 + */ +export function validateNumOrd(num, type) { + let regName = /[^\d.]/g + if (type === 1) { + if (!regName.test(num)) return false + } else if (type === 2) { + regName = /[^\d.]/g + if (!regName.test(num)) return false + } + return true +} + +/** + * 判断是否为空 + */ +export function validateNull(val) { + if (typeof val === 'boolean') { + return false + } + if (typeof val === 'number') { + return false + } + if (val instanceof Array) { + if (val.length === 0) return true + } else if (val instanceof Object) { + if (JSON.stringify(val) === '{}') return true + } else { + return val === 'null' || val == null || val === 'undefined' || val === undefined || val === '' + } + return false +} diff --git a/src/views/iam/user/User.api.ts b/src/views/iam/user/User.api.ts new file mode 100644 index 00000000..04d411d7 --- /dev/null +++ b/src/views/iam/user/User.api.ts @@ -0,0 +1,136 @@ +import { defHttp } from '@/utils/http/axios' +import { PageResult, Result } from '#/axios' +import { BaseEntity } from '#/web' + +/** + * 分页 + */ +export function page(params) { + return defHttp.get>>({ + url: '/user/admin/page', + params, + }) +} + +/** + * 获取单条 + */ +export function get(id) { + return defHttp.get>({ + url: '/user/admin/findById', + params: { id }, + }) +} + +/** + * 添加 + */ +export function add(obj) { + return defHttp.post({ + url: '/user/admin/add', + data: obj, + }) +} + +/** + * 更新 + */ +export function update(obj) { + return defHttp.post({ + url: '/user/admin/update', + data: obj, + }) +} + +/** + * 查询全部 + */ +export function findAll() { + return defHttp.get>>({ + url: '/user/admin/findAll', + }) +} +/** + * 重置密码 + */ +export function restartPassword(userId, newPassword) { + return defHttp.post({ + url: '/user/admin/restartPassword', + params: { userId, newPassword }, + }) +} + +/** + * 批量重置密码 + */ +export function restartPasswordBatch(userIds, newPassword) { + return defHttp.post({ + url: '/user/admin/restartPasswordBatch', + data: userIds, + params: { newPassword }, + }) +} + +/** + * 封禁用户 + */ +export function banUser(userId) { + return defHttp.post({ + url: '/user/admin/ban', + params: { userId }, + }) +} + +/** + * 封禁用户 批量 + */ +export function banUserBatch(userIds) { + return defHttp.post({ + url: '/user/admin/banUserBatch', + data: userIds, + }) +} + +/** + * 解锁用户 + */ +export function unlockUser(userId) { + return defHttp.post({ + url: '/user/admin/unlock', + params: { userId }, + }) +} + +/** + * 解锁用户 + */ +export function unlockUserBatch(userIds) { + return defHttp.post({ + url: '/user/admin/unlockBatch', + data: userIds, + }) +} + +/** + * 用户信息 + */ +export interface UserInfo extends BaseEntity { + // 名称 + name: string + // 账号 + account: string + // 密码 + password?: string + // 确认密码 + confirmPassword?: string + // 手机号 + phone?: string + // 邮箱 + email?: string + // 是否超级管理员 + administrator?: boolean + // 注册时间 + registerTime?: string + // 账号状态 + status?: number +} diff --git a/src/views/iam/user/UserAdd.vue b/src/views/iam/user/UserAdd.vue new file mode 100644 index 00000000..f3061eba --- /dev/null +++ b/src/views/iam/user/UserAdd.vue @@ -0,0 +1,182 @@ + + + + + diff --git a/src/views/iam/user/UserAssign.api.ts b/src/views/iam/user/UserAssign.api.ts new file mode 100644 index 00000000..60c98882 --- /dev/null +++ b/src/views/iam/user/UserAssign.api.ts @@ -0,0 +1,43 @@ +import { defHttp } from '@/utils/http/axios' +import { Result } from '#/axios' +import { Role } from '@/views/iam/role/Role.api' + +/** + * 获取用户拥有角色id集合 + */ +export function getRoleIds(id) { + return defHttp.get>({ + url: `/user/role/findRoleIdsByUser`, + params: { id }, + }) +} + +/** + * 获取用户拥有角色集合 + */ +export function getRoles(id) { + return defHttp.get>({ + url: `/user/role/findRolesByUser`, + params: { id }, + }) +} + +/** + * 添加用户角色关联关系 + */ +export function addUserRole(data) { + return defHttp.post({ + url: `/user/role/saveAssign`, + data: data, + }) +} + +/** + * 添加用户角色关联关系 批量 + */ +export function addUserRoleBatch(data) { + return defHttp.post({ + url: `/user/role/saveAssignBatch`, + data: data, + }) +} diff --git a/src/views/iam/user/UserEdit.vue b/src/views/iam/user/UserEdit.vue new file mode 100644 index 00000000..2a15427e --- /dev/null +++ b/src/views/iam/user/UserEdit.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/src/views/iam/user/UserList.vue b/src/views/iam/user/UserList.vue new file mode 100644 index 00000000..bda2f13f --- /dev/null +++ b/src/views/iam/user/UserList.vue @@ -0,0 +1,293 @@ + + + + + diff --git a/src/views/iam/user/UserShow.vue b/src/views/iam/user/UserShow.vue new file mode 100644 index 00000000..9f750a96 --- /dev/null +++ b/src/views/iam/user/UserShow.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/types/store.d.ts b/types/store.d.ts index 721d9533..c9d42c83 100644 --- a/types/store.d.ts +++ b/types/store.d.ts @@ -33,7 +33,7 @@ export interface UserInfo { // 名称 name: string // 账号 - username: string + account: string // 头像图片id avatar: string }