前台:
<template>
<div class="about">
<el-row>
<el-col :span="16">
<el-form :model="searchFormModel" inline>
<el-form-item label="用户名:">
<el-input v-model="searchFormModel.username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="手机号:">
<el-input v-model="searchFormModel.phone" placeholder="请输入手机号码"></el-input>
</el-form-item>
<el-form-item label="性别:">
<el-select v-model="searchFormModel.sex" placeholder="请选择性别">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" type="success" @click="searchData">查询</el-button>
</el-form-item>
</el-form>
</el-col>
<el-col :span="8">
<el-button type="primary" icon="el-icon-plus" @click="openInsertDialog">用户添加</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deleteUser">批量删除</el-button>
</el-col>
</el-row>
<el-table :data="tableData" @selection-change="handleSelectionChange">
<el-table-column type="selection"></el-table-column>
<!--ID-->
<el-table-column label="ID" prop="id" width="70 sortable">
</el-table-column>
<!-- 用户头像-->
<el-table-column label="用户头像" width="100">
<template slot-scope="scope">
<el-avatar :fit="fit" :size="size" :src="scope.row.userface"></el-avatar>
</template>
</el-table-column>
<!--用户名-->
<el-table-column label="用户名" prop="username" width="100"></el-table-column>
<!--性别-->
<el-table-column label="性别" width="80">
<template slot-scope="scope">
<p v-if="scope.row.sex==0">女</p>
<p v-if="scope.row.sex==1">男</p>
</template>
</el-table-column>
<!--手机号-->
<el-table-column label="手机号" prop="phone" width="140">
<template slot-scope="scope">
<i class="el-icon-mobile-phone"></i>
<span style="margin-left: 5px;">{{scope.row.phone}}</span>
</template>
</el-table-column>
<!--拥有角色-->
<el-table-column label="拥有角色" prop="nameZhs" width="130"></el-table-column>
<!--省市区-->
<el-table-column label="省市区" prop="provinceName" width="150">
<template slot-scope="scope">
{{scope.row.provinceName}}{{scope.row.cityName}}{{scope.row.districtName}}
</template>
</el-table-column>
<!--操作-->
<el-table-column label="操作">
<template slot-scope="scope">
<el-button icon="el-icon-info" @click="openHuiDialog(scope.row)" size="small" type="primary" round>详情</el-button>
<el-button icon="el-icon-edit" @click="openEditDialog(scope.row)" size="small" type="info" round>修改</el-button>
<el-button icon="el-icon-delete" @click="deleteUser(scope.row)" size="small" type="danger" round>删除</el-button>
</template>
</el-table-column>
</el-table>
<el-row>
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="current"
:page-sizes="sizes" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</el-row>
<!-- 添加用户的对话框开始-->
<el-dialog :visible.sync="insertUserDialog" title="添加用户" center width="60%">
<el-form :model="insertFormModel" :rules="insertRules" ref="insertRuleForm" label-width="80px">
<el-form-item label="登录名称" label-width="80px" prop="username">
<el-input v-model="insertFormModel.username" placeholder="请输入登录名称"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="phone" label-width="80px">
<el-input v-model="insertFormModel.phone" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item label="性别" label-width="80px">
<el-radio v-model="insertFormModel.sex" label="1" border>男</el-radio>
<el-radio v-model="insertFormModel.sex" label="0" border>女</el-radio>
</el-form-item>
<!-- 角色 -->
<el-checkbox-group v-model="checkedRole" @change="handleCheckedCitiesChange">
<el-checkbox v-for="u in nameZh" :label="u.id">{{u.nameZh}}</el-checkbox>
</el-checkbox-group>
<el-form-item label="省市区" label-width="80px">
<el-cascader v-model="value" :options="nations" :props="props" @change="handleChange"></el-cascader>
</el-form-item>
<el-form-item label="头像" label-width="80px">
<!--action 上传的地址 name的名称默认是file 就是上传的文件字段名称-->
<!--on-success成功/before 是上传成功触发的钩子函数-->
<el-upload name="file" :show-file-list="false" class="avatar-uploader" action="http://localhost:92/upload"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<!--img上传图片的本地效果-->
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="saveUser('insertRuleForm')">保存</el-button>
<el-button type="success">重置</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!-- 添加用户的对话框结束-->
<!-- 编辑用户的对话框开始-->
<el-dialog :visible.sync="editUserDialog" title="编辑用户" center width="60%">
<el-form :model="editFormModel" ref="editRuleForm" label-width="80px">
<el-form-item label="登录名称" label-width="80px" prop="username">
<el-input v-model="editFormModel.username" placeholder="请输入登录名称"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="phone" label-width="80px">
<el-input v-model="editFormModel.phone" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item label="性别" label-width="80px">
<el-radio v-model="editFormModel.sex" label="1" border>男</el-radio>
<el-radio v-model="editFormModel.sex" label="0" border>女</el-radio>
</el-form-item>
<!-- 角色 -->
<el-checkbox-group v-model="checkedRole" @change="handleCheckedCitiesChange">
<el-checkbox v-for="u in nameZh" :label="u.id">{{u.nameZh}}</el-checkbox>
</el-checkbox-group>
<el-form-item label="省市区" label-width="80px">
<el-cascader
v-model="value"
:options="nations"
:props="props"
@change="handleChange"></el-cascader>
</el-form-item>
<el-form-item label="头像" label-width="80px">
<!--action 上传的地址 name的名称默认是file 就是上传的文件字段名称-->
<!--on-success成功/before 是上传成功触发的钩子函数-->
<el-upload name="file" :show-file-list="false" class="avatar-uploader" action="http://localhost:92/upload" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<!--img上传图片的本地效果-->
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="editUser('editRuleForm')">保存</el-button>
<el-button type="success" >重置</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!-- 编辑用户的对话框结束-->
<!-- 详情用户的对话框开始-->
<el-dialog :visible.sync="HuiUserDialog" title="编辑用户" center width="60%">
<el-form :model="HuiFormModel" label-width="80px">
<el-form-item label="登录名称" label-width="80px" prop="username">
<el-input v-model="HuiFormModel.username" placeholder="请输入登录名称"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="phone" label-width="80px">
<el-input v-model="HuiFormModel.phone" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item label="性别" label-width="80px">
<el-radio v-model="HuiFormModel.sex" label="1" border>男</el-radio>
<el-radio v-model="HuiFormModel.sex" label="0" border>女</el-radio>
</el-form-item>
<!-- 角色 -->
<el-checkbox-group v-model="checkedRole" @change="handleCheckedCitiesChange">
<el-checkbox v-for="u in nameZh" :label="u.id">{{u.nameZh}}</el-checkbox>
</el-checkbox-group>
<el-form-item label="省市区" label-width="80px">
<el-cascader
v-model="value"
:options="nations"
:props="props"
@change="handleChange"></el-cascader>
</el-form-item>
<el-form-item label="头像" label-width="80px">
<!--action 上传的地址 name的名称默认是file 就是上传的文件字段名称-->
<!--on-success成功/before 是上传成功触发的钩子函数-->
<el-upload name="file" :show-file-list="false" class="avatar-uploader" action="http://localhost:92/upload" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<!--img上传图片的本地效果-->
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<!-- <el-form-item>
<el-button type="primary" @click="editUser('editRuleForm')">保存</el-button>
<el-button type="success" >重置</el-button>
</el-form-item> -->
</el-form>
</el-dialog>
<!-- 详情用户的对话框结束-->
</div>
</template>
<script>
export default {
data() {
//自定义规则
var checkPhone = (rule, value, callback) => {
if (!/^1[356789]\d{9}$/.test(value)) {
callback(new Error('手机号输入有误,请重新填写'));
}
callback();
}
return {
tableData: [],
current: 1,
sizes: [3, 5, 8],
size: 50,
pageSize: 3,
total: 0,
fit: 'fill',
imageUrl: '',
searchFormModel: {
sex: '',
phone: '',
username: ''
},
options: [{
value: '1',
label: '男'
}, {
value: '0',
label: '女'
}],
insertUserDialog: false,
insertFormModel: {
username: '',
phone: '',
sex: '1',
userface: '',
province: '',
city: '',
district: '',
roleids: []
},
nameZh: [],
checkedRole: [],
ids: [],
value: [],
nations: [],
props: {
value: 'id',
label: 'name',
children: 'list'
},
insertRules:{
username:[
{required:true,message:'请输入用户名称',trigger:'blur'},
{min:3,max:10,message:'长度在3到10个字符',trigger:'blur'}
],
phone:[
{required:true,message:'请输入手机号',trigger:'blur'},
{validator:checkPhone,trigger:'blur'}
]
},
editUserDialog: false,
editFormModel: {
id:'',
username: '',
phone: '',
sex: '1',
userface: '',
province: '',
city: '',
district: '',
roleids: []
},
HuiUserDialog: false,
HuiFormModel: {
id:'',
username: '',
phone: '',
sex: '1',
userface: '',
province: '',
city: '',
district: '',
roleids: []
}
}
},
created() {
this.initData();
this.initCascader();
},
methods: {
initCascader() {
this.axios.get('http://localhost:92/nation/list').then((res) => {
console.log(res.data)
this.nations = res.data;
})
},
initData() {
this.axios.get('http://localhost:92/user/listVo', {
params: {
current: this.current,
size: this.pageSize,
sex: this.searchFormModel.sex,
phone: this.searchFormModel.phone,
username: this.searchFormModel.username
}
}).then((res) => {
this.tableData = res.data.data.records;
this.total = res.data.data.total;
});
},
handleSelectionChange(val) {
this.ids = [];
if (val != null && val.length > 0) {
for (let i = 0; i < val.length; i++) {
this.ids.push(val[i].id);
}
console.log(this.ids);
}
},
handleSizeChange(val) {
this.pageSize = val;
this.initData();
},
handleCurrentChange(val) {
this.current = val;
this.initData();
},
searchData() {
this.current = 1;
this.initData();
},
openInsertDialog() {
this.axios.get('http://localhost:92/role/findAll').then((res) => {
this.nameZh = res.data
})
//选修课多选框清空
this.checkedRole = [];
//还原三级联动
this.value = [];
//还原图片
this.imageUrl = '';
this.insertUserDialog = true;
},
handleCheckedCitiesChange(val) {
// var check =[];
this.checkedRole = val;
console.log(this.checkedRole);
},
handleAvatarSuccess(res, file) {
if (res.code == 1001) {
if (this.insertUserDialog) {
this.insertFormModel.userface = res.data;
}else if(this.editUserDialog){
this.editFormModel.userface=res.data;
}
this.imageUrl = URL.createObjectURL(file.raw);
}else{
alert("上传失败");
}
},
beforeAvatarUpload(file) {
/*
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
*/
},
handleChange(value) {
console.log(value + "@@@@@")
if (value != null && Array.isArray(value)) {
if(this.insertUserDialog){
this.insertFormModel.province = value[0];
this.insertFormModel.city = value[1];
this.insertFormModel.district = value[2];
}else if(this.editUserDialog){
this.editFormModel.province = value[0];
this.editFormModel.city = value[1];
this.editFormModel.district = value[2];
}
}
},
saveUser(formName) {
this.$refs[formName].validate((valid)=>{
if(valid){
console.log('表单验证通过,可以提交数据')
this.insertFormModel.roleids = this.checkedRole;
this.axios.post('http://localhost:92/user/insertuser', this.insertFormModel).then((res) => {
if (res.data) {
alert('添加成功');
this.insertUserDialog = false;
this.initData();
} else {
alert('添加失败');
}
})
}else{
console.log('表单验证失败,阻止表单提交');
}
})
},
deleteUser(row){
if(this.ids!=''){
this.$alert('请确定要删除的数据','提示',{
confirmButtonText:'确定',
concelButtonText:'取消',
type:'warning'
}).then(()=>{
this.axios.post('http://localhost:92/user/deluser',this.ids).then((res)=>{
if(res.data){
this.$message({
showClose:true,
type:'success',
message:'删除成功'
});
this.initData();
}else{
this.$message({
type:'info',
message:'删除失败'
})
}
})
}).catch(()=>{
this.$message({
type:'info',
message:'取消删除'
})
})
}else{
this.$message({
type: 'warning',
message: '请选择要删除的数据'
});
}
},
openEditDialog(row){
this.axios.get('http://localhost:92/role/findAll').then((res)=>{
this.nameZh=res.data
})
Object.assign(this.editFormModel,row);
//多选框清空
this.checkedRole=[];
//多选框回显
let rids=row.rids;
//还原三级联动
this.value=[];
//还原图片
this.imageUrl='';
//图片回显
this.imageUrl=row.userface;
//判断性别
if(row.sex==0){
this.editFormModel.sex='0';
}else{
this.editFormModel.sex='1';
}
//判断省市区
if(row.province!=null){
this.value.push(row.province);
this.value.push(row.city);
this.value.push(row.district);
}
var array=rids.split(',');
//判断分割出的数组是否为空
if(array!=null && array.length>0){
for(let i=0;i<array.length;i++){
this.checkedRole.push(parseInt(array[i]));
}
}
this.editUserDialog=true;
},
editUser(){
this.editFormModel.roleids=this.checkedRole;
this.axios.post('http://localhost:92/user/updateuser',this.editFormModel).then((res)=>{
if(res.data){
alert('修改成功');
this.editUserDialog=false;
this.initData();
}else{
alert('修改失败');
}
})
},
openHuiDialog(row){
this.axios.get('http://localhost:92/role/findAll').then((res)=>{
this.nameZh=res.data
})
Object.assign(this.HuiFormModel,row);
//多选框清空
this.checkedRole=[];
//多选框回显
let rids=row.rids;
//还原三级联动
this.value=[];
//还原图片
this.imageUrl='';
//图片回显
this.imageUrl=row.userface;
//判断性别
if(row.sex==0){
this.HuiFormModel.sex='0';
}else{
this.HuiFormModel.sex='1';
}
//判断省市区
if(row.province!=null){
this.value.push(row.province);
this.value.push(row.city);
this.value.push(row.district);
}
var array=rids.split(',');
//判断分割出的数组是否为空
if(array!=null && array.length>0){
for(let i=0;i<array.length;i++){
this.checkedRole.push(parseInt(array[i]));
}
}
this.HuiUserDialog=true;
}
}
}
</script>
后台:user控制层
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService iUserService;
@RequestMapping("/listVo")
public ResultEntity listVo(@RequestParam(defaultValue = "1")long current,
@RequestParam(defaultValue = "3")long size,
UserVo vo){
Page page = new Page<>(current,size);
IPage<UserVo> userVoIPage = iUserService.selectPageVo(page, vo);
return ResultEntity.ok(iUserService.selectPageVo(page,vo));
}
@PostMapping("/insertuser")
public boolean insertuser(@RequestBody UserVo vo){
return iUserService.insertuser(vo);
}
@PostMapping("/deluser")
public boolean deluser(@RequestBody Integer[] roleids){
for(Integer rid:roleids){
System.out.println(rid);
}
return iUserService.deluser(roleids);
}
@PostMapping("/updateuser")
public boolean updateuser(@RequestBody UserVo vo){
return iUserService.updateuser(vo);
}
}
user业务层
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
@Autowired
private UserMapper userMapper;
@Autowired
private User_roleMapper user_roleMapper;
@Override
public IPage<UserVo> selectPageVo(Page page, UserVo vo) {
return userMapper.selectPageVo(page,vo);
}
@Override
@Transactional
public boolean insertuser(UserVo vo) {
try{
userMapper.insert(vo);
Integer[] roleids = vo.getRoleids();
for(Integer rid:roleids){
User_role u = new User_role();
u.setUid(vo.getId());
u.setRid(rid);
user_roleMapper.insert(u);
}
return true;
}catch (Exception e){
e.printStackTrace();
}
return false;
}
@Override
@Transactional
public boolean deluser(Integer[] roleids) {
try{
for(Integer rid:roleids){
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("uid",rid);
user_roleMapper.delete(wrapper);
}
userMapper.deleteBatchIds(Arrays.asList(roleids));
return true;
}catch (Exception e){
e.printStackTrace();
}
return false;
}
@Override
@Transactional
public boolean updateuser(UserVo vo) {
try{
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("uid",vo.getId());
user_roleMapper.delete(wrapper);
Integer[] roleids = vo.getRoleids();
for(Integer rid:roleids){
User_role u = new User_role();
u.setUid(vo.getId());
u.setRid(rid);
user_roleMapper.insert(u);
}
userMapper.updateById(vo);
return true;
}catch (Exception e){
e.printStackTrace();
}
return false;
}
}
user 得 mapper配置文件
<select id="selectPageVo" resultType="com.cyq.chengyuqiwork.entity.UserVo">
SELECT
u.*,GROUP_CONCAT(r.nameZh) nameZhs,
GROUP_CONCAT(r.id) rids,
p.province provinceName,
c.city cityName,
d.district districtName
FROM
USER u
LEFT JOIN nation p ON u.province = p.id
LEFT JOIN nation c ON u.city = c.id
LEFT JOIN nation d ON u.district = d.id
LEFT JOIN user_role ur ON u.id = ur.uid
LEFT JOIN role r ON ur.rid = r.id
<where>
u.enabled=1
<if test="vo!=null">
<if test="vo.username!=null and vo.username!=''">
and u.username like concat('%',#{vo.username},'%')
</if>
<if test="vo.phone!=null and vo.phone!=''">
and u.phone=#{vo.phone}
</if>
<if test="vo.sex!=null">
and u.sex=#{vo.sex}
</if>
</if>
</where>
GROUP BY u.id
</select>
文件上传得控制层
@RestController
public class UploadController {
@RequestMapping("/upload")
public ResultEntity upload(MultipartFile file){
try {
//判断上传的文件
if (file != null && !file.isEmpty()) {
//上传的路径
String path = "D:\\pic\\";
//重新命名文件的名称
String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
//创建文件对象
File destFile = new File(path, fileName);
//当前文件进行拷贝
file.transferTo(destFile);
//返回图片的路径地址
return ResultEntity.ok("http://localhost:92/img/" + fileName);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return ResultEntity.err("upload");
}
}
角色控制层
需要单独查询下角色列表
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private IRoleService iRoleService;
@RequestMapping("/findAll")
public List<Role> findAll(){
return iRoleService.selectForlist();
}
}
地区得控制层 (nation)
@RestController
@RequestMapping("/nation")
public class NationController {
@Autowired
private INationService iNationService;
@RequestMapping("/list")
public List<NationVo> findAll(){
return iNationService.findAll();
}
}
地区表得 mapper配置文件
<resultMap id="mapVo" type="com.cyq.chengyuqiwork.entity.NationVo">
<id column="id" property="id"></id>
<result column="provinceName" property="name"></result>
<collection property="list" ofType="com.cyq.chengyuqiwork.entity.NationVo">
<id column="cid" property="id"></id>
<result column="cityName" property="name"></result>
<collection property="list" ofType="com.cyq.chengyuqiwork.entity.NationVo">
<id column="did" property="id"></id>
<result column="districtName" property="name"></result>
</collection>
</collection>
</resultMap>
<select id="findAll" resultMap="mapVo">
SELECT
p.id,
p.province provinceName,
c.id cid,
c.city cityName,
d.id did,
d.district districtName
FROM
nation p
LEFT JOIN nation c ON p.id = c.parent
LEFT JOIN nation d ON c.id = d.parent
WHERE
p.parent = 1;
</select>