@@ -0,0 +1,177 @@ | |||
package cc.smtweb.system.bpm.spring.controller; | |||
import cc.smtweb.framework.core.common.R; | |||
import cc.smtweb.framework.core.common.SwConsts; | |||
import cc.smtweb.framework.core.util.FileUtil; | |||
import cc.smtweb.framework.core.util.JsonUtil; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.io.IOUtils; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import javax.imageio.ImageIO; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import javax.servlet.http.HttpSession; | |||
import java.awt.*; | |||
import java.awt.image.BufferedImage; | |||
import java.io.OutputStream; | |||
import java.io.PrintWriter; | |||
import java.util.Random; | |||
import java.util.concurrent.ThreadLocalRandom; | |||
/** | |||
* Created with IntelliJ IDEA. | |||
* User: AKhh | |||
* Date: 12-12-31 上午11:17 | |||
* 验证码,放入Session | |||
*/ | |||
@Slf4j | |||
@RestController | |||
@RequestMapping("/api") | |||
public class VerifyCodeController { | |||
private final static String CODES = "23456789abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYXZ"; | |||
//生成验证码 | |||
@RequestMapping(value = "/getVerifyCode") | |||
public void getVerifyCode(HttpServletRequest request, HttpServletResponse response) throws Exception { | |||
setNoCache(response); | |||
// 检验码只有4位长 | |||
String code = createCode(); | |||
HttpSession session = request.getSession(true); | |||
session.setAttribute(SwConsts.LOGIN_VERIFY_CODE, code); //将验证码写入session; | |||
// 在内存中创建图象 | |||
int count = code.length(); | |||
int fontSize = 28; //code的字体大小 | |||
int fontMargin = fontSize / 18; //字符间隔 | |||
int width = 90; //图片长度 | |||
int height = 40; //图片高度,根据字体大小自动调整;调整这个系数可以调整字体占图片的比例 | |||
int avgWidth = (int) (width / count / 1.2); //字符平均占位宽度 | |||
int maxDegree = 26; //最大旋转度数 | |||
//生成随机类 | |||
ThreadLocalRandom random = ThreadLocalRandom.current(); | |||
//背景颜色 | |||
Color bkColor = Color.WHITE; | |||
Color bdColor = new Color(220,223,230); | |||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); | |||
Graphics2D g = image.createGraphics(); | |||
//填充底色为灰白 | |||
g.setColor(bkColor); | |||
g.fillRect(0, 0, width, height); | |||
//画边框 | |||
g.setColor(bdColor); | |||
g.drawRect(0, 0, width - 1, height - 1); | |||
//画干扰字母、数字 | |||
int dSize = (int) (fontSize / 2.5); //调整分母大小以调整干扰字符大小 | |||
Font font = new Font("Fixedsys", Font.PLAIN, dSize); | |||
g.setFont(font); | |||
int dNumber = width * height * 2 / dSize / dSize;//根据面积计算干扰字母的个数 | |||
for (int i = 0; i < dNumber; i++) { | |||
char d_code = CODES.charAt(random.nextInt(CODES.length())); | |||
g.setColor(getRandColor(100, 150)); | |||
g.drawString(String.valueOf(d_code), random.nextInt(width), random.nextInt(height)); | |||
} | |||
//开始画验证码: | |||
// 创建字体 | |||
font = new Font(Font.MONOSPACED, Font.ITALIC | Font.BOLD, fontSize); | |||
// 设置字体 | |||
g.setFont(font); | |||
for (int i = 0; i < count; i++) { | |||
char c = code.charAt(i); | |||
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));//随机选取一种颜色 | |||
//随机旋转一个角度[-maxDegre, maxDegree] | |||
int degree = random.nextInt(-maxDegree, maxDegree + 1); | |||
//偏移系数,和旋转角度成反比,以避免字符在图片中越出边框 | |||
double offsetFactor = 1 - (Math.abs(degree) / (maxDegree + 1.0));//加上1,避免出现结果为0 | |||
g.rotate(degree * Math.PI / 180); //旋转一个角度 | |||
int x_bound = avgWidth - fontSize; | |||
if (x_bound < 0) x_bound = 1; | |||
int x = (int) ((fontMargin * (i - 1)) + random.nextInt(x_bound) * offsetFactor) - 8; //横向偏移的距离 | |||
int y = (int) (fontSize + random.nextInt(height - fontSize) * offsetFactor); //上下偏移的距离 | |||
g.rotate(-degree * Math.PI / 180); //画完一个字符之后,旋转回原来的角度 | |||
g.translate(avgWidth, 0);//移动到下一个画画的原点 | |||
g.drawString(String.valueOf(c), x, y); //x,y是字符的左下角,偏离原点的距离!!! | |||
//System.out.println(c+": x="+x+" y="+y+" degree="+degree+" offset="+offsetFactor); | |||
//X、Y坐标在合适的范围内随机,不旋转: | |||
//g.drawString(String.valueOf(c), width / count * i + random.nextInt(width / count - fontSize), fontSize + random.nextInt(height - fontSize)); | |||
} | |||
g.dispose(); | |||
writeResponseJson(response, JsonUtil.encodeString(R.success(FileUtil.imgToBase64(image)))); | |||
} | |||
private void writeResponseJson(HttpServletResponse response, String ret) { | |||
response.setHeader("Pragma", "No-cache"); | |||
response.setHeader("Cache-Control", "no-cache"); | |||
response.setDateHeader("Expires", 0L); | |||
response.setContentType("application/json;charset=UTF-8"); | |||
PrintWriter writer = null; | |||
try { | |||
writer = response.getWriter(); | |||
writer.write(ret); | |||
writer.flush(); | |||
} catch (Exception e) { | |||
log.error("response error", e); | |||
} finally { | |||
if (writer != null) { | |||
writer.close(); | |||
} | |||
} | |||
} | |||
private void setNoCache(HttpServletResponse response) { | |||
response.setHeader("Pragma", "No-cache"); | |||
response.setHeader("Cache-Control", "no-cache"); | |||
response.setDateHeader("Expires", 0); | |||
} | |||
//生成验证码内容 | |||
private String createCode() { | |||
//生成随机类 | |||
Random random = new Random(); | |||
// 生成四个随机数 | |||
int a = random.nextInt(CODES.length()); | |||
int b = random.nextInt(CODES.length()); | |||
int c = random.nextInt(CODES.length()); | |||
int d = random.nextInt(CODES.length()); | |||
StringBuilder sb = new StringBuilder(4); | |||
sb.append(CODES.charAt(a)).append(CODES.charAt(b)).append(CODES.charAt(c)).append(CODES.charAt(d)); | |||
return sb.toString(); | |||
} | |||
private String createCodeEx() { | |||
//生成随机类 | |||
Random random = new Random(); | |||
// 生成四个随机数 | |||
int a = random.nextInt(10); | |||
int b = random.nextInt(10); | |||
int c = random.nextInt(10); | |||
int d = random.nextInt(10); | |||
StringBuilder sb = new StringBuilder(4); | |||
sb.append(a).append(b).append(c).append(d); | |||
return sb.toString(); | |||
} | |||
//给定范围获得随机颜色 | |||
private Color getRandColor(int fc, int bc) { | |||
Random random = new Random(); | |||
if (fc > 255) fc = 255; | |||
if (bc > 255) bc = 255; | |||
int r = fc + random.nextInt(bc - fc); | |||
int g = fc + random.nextInt(bc - fc); | |||
int b = fc + random.nextInt(bc - fc); | |||
return new Color(r, g, b); | |||
} | |||
} |
@@ -146,6 +146,7 @@ public class RoleHandler { | |||
MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id); | |||
if (item == null) return SwListData.create(list, 0); | |||
Menu menu = MenuCache.getInstance().get(item.getMenu()); | |||
if (menu == null) return SwListData.create(list, 0); | |||
ModelForm mf = ModelFormCache.getInstance().get(menu.getPageId()); | |||
for (String f : menu.getRightSet(SwEnum.MenuRightType.FIELD.value)) { | |||
String name = getFieldName(mf, f); | |||
@@ -180,6 +181,7 @@ public class RoleHandler { | |||
MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id); | |||
if (item == null) return SwListData.create(list, 0); | |||
Menu menu = MenuCache.getInstance().get(item.getMenu()); | |||
if (menu == null) return SwListData.create(list, 0); | |||
for (String f : menu.getRightSet(SwEnum.MenuRightType.FUNC.value)) { | |||
if (PubUtil.isEmpty(f)) continue; | |||
SwMap row = new SwMap(); | |||
@@ -212,6 +214,7 @@ public class RoleHandler { | |||
MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id); | |||
if (item == null) return SwListData.create(list, 0); | |||
Menu menu = MenuCache.getInstance().get(item.getMenu()); | |||
if (menu == null) return SwListData.create(list, 0); | |||
RoleRightContent rc = new RoleRightContent(role.getPrivilege()); | |||
Map<String, Object> data = rc.getDataRight(item.getId()); | |||
@@ -6,13 +6,20 @@ window.$swEvent.setup("bpm.sys.user.role.roleRight", { | |||
setup(page) { | |||
const {$params, $refs, $widgets, $model, $utils, $tabRouter, $api} = page || {}; | |||
const {$$message, $$http} = $utils || {}; | |||
const temp_mp_id = ""; | |||
// 示例 | |||
const onBeforeSave = () => { | |||
$model.rightData.setFormVal("data", $model.roleDataList.data.list.rows); | |||
}; | |||
const onRoleSelect = (row) => { | |||
if (this.temp_mp_id !== row["srl_id"]) { | |||
$model.menuData.setFormVal("mp_id", ""); | |||
} | |||
this.temp_mp_id = row["srl_id"]; | |||
} | |||
return { | |||
onBeforeSave, | |||
onRoleSelect, | |||
} | |||
} | |||
}); |
@@ -18,4 +18,7 @@ public interface SwConsts { | |||
String PARAM_ROWS = "rows"; | |||
String TOTAL_KEY = "total_count"; | |||
String DEF_DB_NAME = "sys"; | |||
String LOGIN_VERIFY_CODE = "_VERIFY_CODE"; | |||
String _LOGIN_USER_ID_IN_SESSION = "_LOGIN_USER_ID_IN_SESSION"; | |||
} |
@@ -1,31 +1,81 @@ | |||
package cc.smtweb.framework.core.session; | |||
import cc.smtweb.framework.core.common.SwConsts; | |||
import cc.smtweb.framework.core.util.IpAddrUtil; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpSession; | |||
import java.io.Serializable; | |||
/** | |||
* 用户会话缓存,前端调用API时传输 Auto_Token 参数来查找用户会话 | |||
* | |||
* @author xkliu | |||
*/ | |||
@Getter @Setter | |||
@Getter | |||
@Setter | |||
public class UserSession implements Serializable { | |||
private static final long serialVersionUID = 3854315462714888716L; | |||
// | |||
private String sessionId = null; //sessionId | |||
//登录时间 | |||
private Long loginTimeMillis; | |||
//最后请求时间 | |||
private Long lastTimeMillis = 0L; | |||
//ID | |||
private String loginIp; | |||
// 用户ID | |||
private long userId; | |||
// 当前组织ID | |||
private long companyId; | |||
// 当前机构ID | |||
private long partyId; | |||
// 站点ID | |||
private long siteId; | |||
// 终端类型 | |||
private byte terminalType; | |||
public UserSession() { | |||
} | |||
public UserSession(HttpServletRequest request, long user_id) { | |||
this(request, user_id, (byte) 0); | |||
} | |||
public UserSession(HttpServletRequest request, long user_id, byte terminalType) { | |||
this.loginIp = IpAddrUtil.getIpAddr(request); | |||
this.userId = user_id; | |||
this.terminalType = terminalType; | |||
HttpSession session = request.getSession(true); | |||
if (user_id > 0) session.setAttribute(SwConsts._LOGIN_USER_ID_IN_SESSION, getUserKey()); | |||
this.sessionId = session.getId(); | |||
this.loginTimeMillis = System.currentTimeMillis(); | |||
this.lastTimeMillis = this.loginTimeMillis; | |||
} | |||
//模拟 | |||
public UserSession(long user_id) { | |||
this(user_id, (byte) 0); | |||
} | |||
public UserSession(long user_id, byte terminalType) { | |||
this.userId = user_id; | |||
this.terminalType = terminalType; | |||
this.loginTimeMillis = System.currentTimeMillis(); | |||
} | |||
public static UserSession createSys() { | |||
UserSession us = new UserSession(); | |||
us.userId = 1; | |||
us.companyId = 1; | |||
us.partyId = 1; | |||
us.terminalType = 0; | |||
return us; | |||
return us; | |||
} | |||
public String getUserKey() { | |||
return userId + "_" + terminalType; | |||
} | |||
} |
@@ -1,12 +1,13 @@ | |||
package cc.smtweb.framework.core.util; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.codec.binary.Base64; | |||
import org.apache.commons.io.FileUtils; | |||
import sun.misc.BASE64Encoder; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
import java.io.UnsupportedEncodingException; | |||
import javax.imageio.ImageIO; | |||
import java.awt.image.BufferedImage; | |||
import java.io.*; | |||
import java.nio.charset.Charset; | |||
import java.nio.charset.StandardCharsets; | |||
@@ -57,4 +58,43 @@ public class FileUtil { | |||
return null; | |||
} | |||
} | |||
/** | |||
* 将图片转换为base64编码后的字符串 | |||
* | |||
* @param path | |||
* @return | |||
* @throws Exception | |||
*/ | |||
public static String imgToBase64(String path) throws Exception { | |||
return imgToBase64(new FileInputStream(path)); | |||
} | |||
public static String imgToBase64(File file) throws Exception { | |||
return imgToBase64(new FileInputStream(file)); | |||
} | |||
public static String imgToBase64(InputStream in) throws Exception { | |||
byte[] data = null; | |||
data = new byte[in.available()]; | |||
in.read(data); | |||
in.close(); | |||
Base64 encoder = new Base64(); | |||
return encoder.encodeAsString(data); | |||
} | |||
public static String imgToBase64(BufferedImage bufferedImage) { | |||
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流 | |||
try { | |||
ImageIO.write(bufferedImage, "png", baos);//写入流中 | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
byte[] bytes = baos.toByteArray();//转换成字节 | |||
BASE64Encoder encoder = new BASE64Encoder(); | |||
String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串 | |||
png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n | |||
return "data:image/png;base64," + png_base64; | |||
} | |||
} |