diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/VerifyCodeController.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/VerifyCodeController.java new file mode 100644 index 0000000..0e8fa13 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/VerifyCodeController.java @@ -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); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHandler.java index 361edac..bf1299a 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHandler.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHandler.java @@ -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 data = rc.getDataRight(item.getId()); diff --git a/smtweb-framework/bpm/src/main/resources/static/event/bpm/sys/user/role/roleRight.js b/smtweb-framework/bpm/src/main/resources/static/event/bpm/sys/user/role/roleRight.js index 772292d..df51ca5 100644 --- a/smtweb-framework/bpm/src/main/resources/static/event/bpm/sys/user/role/roleRight.js +++ b/smtweb-framework/bpm/src/main/resources/static/event/bpm/sys/user/role/roleRight.js @@ -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, } } }); diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java index d20aeda..7c2a372 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java @@ -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"; } diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSession.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSession.java index 492c6cf..226a9dc 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSession.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSession.java @@ -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; } } diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java index 48aab8c..551382f 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java @@ -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; + } }