前端设计
使用npm创建web工程
通过以下命令创建一个web工程
vue init webpack shiroui
添加axios
,用于请求后端服务
cnpm install axios --save
在工程main.js
中引入axios
Vue.config.productionTip = false
axios.defaults.baseURL = 'localhost:8080'
Vue.prototype.$axios = axios
添加elementui
cnpm i element-ui -S
在工程main.js
中引入elementui
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
···
Vue.use(ElementUI)
main.js
预览
实现登录功能
前端界面
<template>
<div id="app">
<el-form ref="form" :model="user" label-width="80px">
<el-form-item label="用户编号">
<el-input v-model="user.userCode" placeholder="请输入用户编号"></el-input>
</el-form-item>
<el-form-item label="密 码">
<el-input v-model="user.password" placeholder="请输入密码" show-password></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">登录</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">用户管理</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/role' }">角色管理</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/permission' }">权限管理</el-breadcrumb-item>
<el-breadcrumb-item>角色分配</el-breadcrumb-item>
<el-breadcrumb-item>权限分配</el-breadcrumb-item>
</el-breadcrumb>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
user: {
userCode: undefined,
password: undefined
}
}
},
methods: {
onSubmit: function () {
debugger
this.$axios({
method: 'post',
url: '/shiro/login',
params: this.user
}).then(result => {
this.$message(result.data)
}).catch(e => {
console.log(e)
})
}
}
}
</script>
<style>
</style>
登录后端代码
/**
* @author laughing
* @date 2020/10/11
* @site https://www.lisen.org
*/
@RestController
@RequestMapping("/shiro")
public class ShiroController {
private final Logger logger = LoggerFactory.getLogger(ShiroController.class);
@Resource
ShiroService shiroService;
@RequestMapping("/findUserByUserCode")
public ShiroUser findUserByUserCode() {
String userCode = "lisen";
ShiroUser shiroUser = shiroService.findUserByCode(userCode);
return shiroUser;
}
@RequestMapping("/login")
public String login(@RequestParam("userCode") String userCode, @RequestParam("password") String password) {
// password = new SimpleHash(AuthenConst.HASH_ALGORITHM_NAME,password,AuthenConst.SALT,AuthenConst.HASH_INTERACTIONS).toHex();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userCode, password);
Subject subject = SecurityUtils.getSubject();
try {
//进行验证,这里可以捕获异常,然后返回对应信息
subject.login(usernamePasswordToken);
} catch (UnknownAccountException e) {
logger.error("用户名不存在!", e);
return "用户名不存在!";
} catch (AuthenticationException e) {
logger.error("账号或密码错误!", e);
return "账号或密码错误!";
} catch (AuthorizationException e) {
logger.error("没有权限!", e);
return "没有权限";
}
return "login success";
}
@RequestMapping("/index")
public String index(String userCode, String password) {
return "index";
}
@RequiresPermissions("permission")
@RequestMapping("/permission")
public String permission() {
return "permission";
}
@RequiresPermissions("dept:add")
@RequestMapping("/deptadd")
public String deptAdd() {
return "dept:add";
}
@RequestMapping("/nopermission")
public String noPermission() {
return "noPermission";
}
}
前端权限调用
<template>
<div>
<el-form>
<el-form-item>
<el-button @click="findAll">加载用户信息</el-button>
<el-button @click="dialogFormVisible=true">增加用户</el-button>
<el-button @click="dialogFormRoleVisible=true">分配岗位</el-button>
</el-form-item>
</el-form>
<el-table :data="tableData" style="width: 100%">
<el-table-column label="ID" width="180">
<template slot-scope="scope">
<i class="el-icon-time"></i>
<span style="margin-left: 10px">{{ scope.row.id }}</span>
</template>
</el-table-column>
<el-table-column label="用户编号" width="180">
<template slot-scope="scope">
<span style="margin-left: 10px">{{ scope.row.userCode }}</span>
</template>
</el-table-column>
<el-table-column label="用户姓名" width="180">
<template slot-scope="scope">
<span style="margin-left: 10px">{{ scope.row.userName }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 增加用户-->
<el-dialog title="增加用户" :visible.sync="dialogFormVisible">
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="用户编号" prop="userCode">
<el-input v-model="form.userCode" autocomplete="off" maxlength="30" show-word-limit></el-input>
</el-form-item>
<el-form-item label="用户名称">
<el-input v-model="form.userName" autocomplete="off" maxlength="30" show-word-limit></el-input>
</el-form-item>
<el-form-item label="密 码">
<el-input v-model="form.password" autocomplete="off" maxlength="30" show-word-limit></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="submitForm">确 定</el-button>
</div>
</el-dialog>
<!-- 分配角色-->
<el-dialog title="分配角色" :visible.sync="dialogFormRoleVisible">
<el-form :model="roleForm" :rules="roleRules" ref="roleForm">
<el-autocomplete
popper-class="my-autocomplete"
v-model="state"
:fetch-suggestions="querySearch"
placeholder="请输入内容"
@select="handleSelect">
<i
class="el-icon-edit el-input__icon"
slot="suffix"
@click="handleIconClick">
</i>
<template slot-scope="{ item }">
<div class="name">{{ item.value }}</div>
<span class="addr">{{ item.address }}</span>
</template>
</el-autocomplete>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormRoleVisible = false">取 消</el-button>
<el-button type="primary" @click="submitFormRole">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data () {
return {
tableData: [],
dialogFormVisible: false,
dialogFormRoleVisible: false,
form: {
userCode: '',
userName: '',
password: ''
},
rules: {
userCode: [
{required: true, message: '请输入用户编号', trigger: 'blur'}
]
},
roleForm: {},
restaurants: [],
state: ''
}
},
methods: {
handleEdit (index, row) {
console.log(index, row)
},
handleDelete (index, row) {
console.log(index, row)
},
findAll () {
const _this = this
this.$axios({
method: 'post',
url: '/user/findAll'
}).then(function (result) {
_this.tableData = result.data
}).catch(function (err) {
console.log(err)
})
},
submitForm: function () {
debugger
this.$refs['form'].validate((valid) => {
if (valid) {
this.dialogFormVisible = false
this.$axios({
method: 'post',
params: this.form,
url: '/user/insert'
})
} else {
return false
}
})
},
submitFormRole: function () {
debugger
const self = this
this.$refs['roleForm'].validate((valid) => {
if (valid) {
// this.dialogFormRoleVisible = false
this.$axios({
method: 'post',
params: this.form,
url: '/user/setRole'
}).then(function (response) {
self.$message(response.data)
})
} else {
return false
}
})
},
querySearch (queryString, cb) {
var restaurants = this.restaurants
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
// 调用 callback 返回建议列表的数据
cb(results)
},
createFilter (queryString) {
return (restaurant) => {
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
}
},
loadAll () {
return [
{'value': '三全鲜食(北新泾店)', 'address': '长宁区新渔路144号'},
{'value': 'Hot honey 首尔炸鸡(仙霞路)', 'address': '上海市长宁区淞虹路661号'},
{'value': '新旺角茶餐厅', 'address': '上海市普陀区真北路988号创邑金沙谷6号楼113'},
{'value': '泷千家(天山西路店)', 'address': '天山西路438号'},
{'value': '胖仙女纸杯蛋糕(上海凌空店)', 'address': '上海市长宁区金钟路968号1幢18号楼一层商铺18-101'},
{'value': '贡茶', 'address': '上海市长宁区金钟路633号'},
{'value': '豪大大香鸡排超级奶爸', 'address': '上海市嘉定区曹安公路曹安路1685号'},
{'value': '茶芝兰(奶茶,手抓饼)', 'address': '上海市普陀区同普路1435号'},
{'value': '十二泷町', 'address': '上海市北翟路1444弄81号B幢-107'},
{'value': '星移浓缩咖啡', 'address': '上海市嘉定区新郁路817号'},
{'value': '阿姨奶茶/豪大大', 'address': '嘉定区曹安路1611号'},
{'value': '新麦甜四季甜品炸鸡', 'address': '嘉定区曹安公路2383弄55号'},
{'value': 'Monica摩托主题咖啡店', 'address': '嘉定区江桥镇曹安公路2409号1F,2383弄62号1F'},
{'value': '浮生若茶(凌空soho店)', 'address': '上海长宁区金钟路968号9号楼地下一层'},
{'value': 'NONO JUICE 鲜榨果汁', 'address': '上海市长宁区天山西路119号'},
{'value': 'CoCo都可(北新泾店)', 'address': '上海市长宁区仙霞西路'},
{'value': '快乐柠檬(神州智慧店)', 'address': '上海市长宁区天山西路567号1层R117号店铺'},
{'value': 'Merci Paul cafe', 'address': '上海市普陀区光复西路丹巴路28弄6号楼819'},
{'value': '猫山王(西郊百联店)', 'address': '上海市长宁区仙霞西路88号第一层G05-F01-1-306'},
{'value': '枪会山', 'address': '上海市普陀区棕榈路'},
{'value': '纵食', 'address': '元丰天山花园(东门) 双流路267号'},
{'value': '钱记', 'address': '上海市长宁区天山西路'},
{'value': '壹杯加', 'address': '上海市长宁区通协路'},
{'value': '唦哇嘀咖', 'address': '上海市长宁区新泾镇金钟路999号2幢(B幢)第01层第1-02A单元'},
{'value': '爱茜茜里(西郊百联)', 'address': '长宁区仙霞西路88号1305室'},
{'value': '爱茜茜里(近铁广场)', 'address': '上海市普陀区真北路818号近铁城市广场北区地下二楼N-B2-O2-C商铺'},
{'value': '鲜果榨汁(金沙江路和美广店)', 'address': '普陀区金沙江路2239号金沙和美广场B1-10-6'},
{'value': '开心丽果(缤谷店)', 'address': '上海市长宁区威宁路天山路341号'},
{'value': '超级鸡车(丰庄路店)', 'address': '上海市嘉定区丰庄路240号'},
{'value': '妙生活果园(北新泾店)', 'address': '长宁区新渔路144号'},
{'value': '香宜度麻辣香锅', 'address': '长宁区淞虹路148号'},
{'value': '凡仔汉堡(老真北路店)', 'address': '上海市普陀区老真北路160号'},
{'value': '港式小铺', 'address': '上海市长宁区金钟路968号15楼15-105室'},
{'value': '蜀香源麻辣香锅(剑河路店)', 'address': '剑河路443-1'},
{'value': '北京饺子馆', 'address': '长宁区北新泾街道天山西路490-1号'},
{'value': '饭典*新简餐(凌空SOHO店)', 'address': '上海市长宁区金钟路968号9号楼地下一层9-83室'},
{'value': '焦耳·川式快餐(金钟路店)', 'address': '上海市金钟路633号地下一层甲部'},
{'value': '动力鸡车', 'address': '长宁区仙霞西路299弄3号101B'},
{'value': '浏阳蒸菜', 'address': '天山西路430号'},
{'value': '四海游龙(天山西路店)', 'address': '上海市长宁区天山西路'},
{'value': '樱花食堂(凌空店)', 'address': '上海市长宁区金钟路968号15楼15-105室'},
{'value': '壹分米客家传统调制米粉(天山店)', 'address': '天山西路428号'},
{'value': '福荣祥烧腊(平溪路店)', 'address': '上海市长宁区协和路福泉路255弄57-73号'},
{'value': '速记黄焖鸡米饭', 'address': '上海市长宁区北新泾街道金钟路180号1层01号摊位'},
{'value': '红辣椒麻辣烫', 'address': '上海市长宁区天山西路492号'},
{'value': '(小杨生煎)西郊百联餐厅', 'address': '长宁区仙霞西路88号百联2楼'},
{'value': '阳阳麻辣烫', 'address': '天山西路389号'},
{'value': '南拳妈妈龙虾盖浇饭', 'address': '普陀区金沙江路1699号鑫乐惠美食广场A13'}
]
},
handleSelect (item) {
console.log(item)
},
handleIconClick (ev) {
console.log(ev)
}
},
mounted () {
this.restaurants = this.loadAll()
}
}
</script>
<style>
.my-autocomplete {
li {
line-height: normal;
padding: 7px;
.name {
text-overflow: ellipsis;
overflow: hidden;
}
.addr {
font-size: 12px;
color: #b4b4b4;
}
.highlighted .addr {
color: #ddd;
}
}
}
</style>
后端权限调用
/**
* @author laughing
* @date 2020/10/13
* @site https://www.xiangcaowuyu.net
*/
@RestController
@RequestMapping("user")
public class UserController {
@Resource
ShiroUserService shiroUserService;
/**
* 查找所有用户
* @return
*/
@RequiresPermissions("user:find")
@RequestMapping("/findAll")
public List<ShiroUser> findAll() {
return shiroUserService.findAll();
}
/**
* 查找所有用户
* @return
*/
@RequiresPermissions("user:find")
@RequestMapping("/insert")
public int save(ShiroUser shiroUser) {
return shiroUserService.insert(shiroUser);
}
}
造福于民的好东西,分享是最好的奉献