1、需求场景
用户可以在某模块某条数据详情界面上复制此详情的链接,并将此链接引入到wiki或其他文档中,其他用户阅读文档时,可通过此链接直接查看某模块某条数据详情。
2020第一篇,就把某模块称为“新年模块”吧~~
2、功能点
①详情中新增“复制链接”功能,此链接中包含新年编号作为标识。
②用户在浏览器地址栏直接访问详情链接,系统自动弹出此链接对应的新年详情Dialog。
3、整体思路
因为左侧菜单和右侧页面都是包含在index中,所以可以通过index页面入手。在index页面创建隐藏文本框,用来存放新年编号,根据新年编号是否为空来判断是否需要弹出详情框。
4、触发状态以及实现方式
根据需求,结合实际场景,此功能的触发状态可分为两种:用户已登录状态、用户未登录状态。
4.1、用户已登录状态
①Controller中新增与链接中请求地址匹配的接口,可通过Get请求直接调用。接口中通过重定向,将请求重定向至/index,重定向过程中通过RedirectAttributes传递新年编号参数,在/index中接收新年编号参数,并将其通过ModelMap传递给index页面。(若不用重定向,页面中地址栏的信息会变成我们粘贴进的链接,导致每次使用F5刷新,都会弹出新年详情)
// 系统首页
@GetMapping("/index")
public String index(ModelMap mmap)
{
// 取身份信息
SysUser user = ShiroUtils.getSysUser();
// 根据用户id取出菜单
List menus = menuService.selectMenusByUser(user);
mmap.put("menus", menus);
mmap.put("user", user);
mmap.put("copyrightYear", Global.getCopyrightYear());
mmap.put("demoEnabled", Global.isDemoEnabled());
//将新年编号传给页面
mmap.put("newyearnunmber",mmap.get("newyearnunmber"));
return "index";
}
// 已登陆状态直接通过链接访问新年详情
@GetMapping("/system/newyear/detail/link/{id}")
public String indexlink(@PathVariable("id") Long newyearnumber, RedirectAttributes model)
{
model.addFlashAttribute("newyearnunmber",newyearnumber);
return "redirect:/index";
}
②给页面body添加onload事件,页面加载完成后,通过判断新年编号文本框是否有值来判断是否弹出详情框。
记得给body绑定onload事件
//body加载成功后,若newyearnunmber不为undefined则自动弹出新年详情
function newyeardetail() {
let val = $("#newyearnunmber").val();
if (val != undefined && val != null & val != "") {
var options = {
title: "新年详情",
width: 800,
height: ($(window).height() - 50),
url: ctx + "/system/newyear/detail/"+val,
skin: 'layui-layer-gray',
btn: ['关闭'],
yes: function (index, layero) {
layer.close(index);
}
};
$.modal.openOptions(options);
}
$("#newyearnunmber").val('');
}
4.2、用户未登录状态
实现方式与用户已登录状态的大致相同,唯一不同的是用户未登录时访问链接,由于未登录会被拦截,跳转至登录页面,所以在登陆的时候需要记住原请求地址,并在登录成功后访问原去请求地址。
所以在登录接口上要稍作修改:
①登录接口添加参数,用于重定向时参数传递。
②登录成功后,检测是否有原请求,若有跳转至原请求,若没有则直接跳转至index。
//直接重定向访问项目,若直接返回index跳转,浏览器地址栏中会带着ticket等信息,导致界面无法刷新
//shiro在跳转前有记录跳转前的页面。前没有认证的用户请求需要认证的链接时,
//shiro在跳转前会把跳转过来的页面链接保存到session的attribute中,
//key的值叫shiroSavedRequest,我们可以能过WebUtils类拿到
SavedRequest savedRequest = WebUtils.getSavedRequest(request);
//若savedRequest != null则证明在访问某请求时检测到未登录,而跳转到登录界面,登陆后需访问原请求地址
if(savedRequest != null){
String requestUrl = savedRequest.getRequestUrl();
if(requestUrl.contains("/system/newyear/detail/link")){
String[] split = requestUrl.split("/");
//将newyearnunmber传递给下一个请求
model.addFlashAttribute("newyearnunmber",split[split.length-1]);
return "redirect:index";
}
}
4.3、“复制链接”功能
复制功能是通过document.execCommand("Copy")来实现的,但是只针对非hidden的input和textarea。而我不想把链接展示在界面上,所以通过追加非hidden的input又给移除的方式实现的。
function copyUrl() {
var oInput = document.createElement('input');
//协议+域名+请求地址+参数
oInput.value = window.location.protocol+"//"+window.location.host+"/PMDHitchManager/system/hitch/detail/link/"+$("#hitchNumber").val();
$(oInput).css({opacity:'0'});
$(oInput).attr({name:"temp_link_input"});
document.body.appendChild(oInput);
oInput.select(); // 选择对象
document.execCommand("Copy"); // 执行浏览器复制命令
oInput.className = 'oInput';
alert('复制成功');
$("input[name='temp_link_input']").remove();
}