All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.benma666.sjsj.web.LjqManager Maven / Gradle / Ivy

/**
 * Project Name:myutils
 * Date:2018年12月16日
 * Copyright (c) 2018, jingma All Rights Reserved.
 */

package cn.benma666.sjsj.web;

import cn.benma666.constants.SysAuth;
import cn.benma666.constants.UtilConst;
import cn.benma666.dict.Cllx;
import cn.benma666.dict.LjqType;
import cn.benma666.domain.SysQxYhxx;
import cn.benma666.domain.SysSjglFile;
import cn.benma666.domain.SysSjglSjdx;
import cn.benma666.exception.MyException;
import cn.benma666.iframe.*;
import cn.benma666.json.JsonUtil;
import cn.benma666.myutils.StringUtil;
import cn.benma666.params.Sys;
import cn.benma666.sjsj.myutils.MyTransactional;
import cn.benma666.sjsj.myutils.ThreadPool;
import cn.benma666.sjzt.Db;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson.JSONObject;
import org.beetl.sql.core.DSTransactionManager;
import org.beetl.sql.core.SQLManager;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

import static cn.benma666.constants.UtilConstInstance.*;

/**
 * 系统-数据管理-拦截器管理 
* date: 2018年12月16日
* @author jingma */ @Component public class LjqManager extends BasicObject { /** * 日志对象 */ private static final Log log = LogFactory.get(); /** * spring容器,可以从中获取注册的bean */ private static ApplicationContext context; /** * 虚拟对象 */ private static SysSjglSjdx xndx; /** * 拦截器map */ private static Map ljqMap=new HashMap<>(); /** * http请求响应对象 */ private static final ThreadLocal httpServletResponseITL = new ThreadLocal<>(); /** * http请求对象 */ private static final ThreadLocal HttpServletRequestITL = new ThreadLocal<>(); /** * 参数对象的线程变量 */ private static final ThreadLocal mpITL = new ThreadLocal<>(); /** * @return 当前线程的参数对象,若当前接口可能被其他接口内部调用则请不要使用本方法,可能导致错乱,获取其他接口的参数 */ public static MyParams getMyParams(){ return mpITL.get(); } /** * 设置当前线程的参数对象 */ public static void setMyParams(MyParams myParams){ if(myParams==null){ mpITL.remove(); }else { mpITL.set(myParams); } } /** * 获取当前线程数据对象的数据库工具,若当前接口可能被其他接口内部调用则请不要使用本方法,可能导致错乱 */ public static Db getDb(){ return Db.db(getMyParams().sjdx().getDxzt()); } /** * 获取当前线程数据对象的SqlManager,若当前接口可能被其他接口内部调用则请不要使用本方法,可能导致错乱 */ public static SQLManager getSqlManager(){ return getDb().getSqlManager(); } public LjqManager(ApplicationContext context){ LjqManager.context = context; //给虚拟对象赋值 xndx = new SysSjglSjdx(); xndx.setId("912769435779405698B51852FB4277DB"); } /** * 使用对应的拦截器
* 对象中配置的拦截器>对象代码注解设置的拦截器>默认拦截器 * @param sjdx 数据对象 * @param ljqType 拦截器类型 * @return 拦截器 * @author jingma */ private static LjqInterface use(SysSjglSjdx sjdx, LjqType ljqType) { if(sjdx==null){ //没有数据对象就采用虚拟对象获取拦截器 sjdx = xndx; } String ljqStr; switch (ljqType){ case dzljq: ljqStr = sjdx.getLjq(); if(isBlank(ljqStr)){ //没有在对象中配置拦截器 if(!isBlank(sjdx.getDxdm())){ ljqStr = sjdx.getDxdm(); }else { //没有定制拦截器 return null; } } break; case dzmrlqj: ljqStr = Conf.getUtilConfig().getLjqDefault(); if(isBlank(ljqStr)){ return null; } break; case kjmrljq: ljqStr = DefaultLjq.class.getName(); break; default: throw new IllegalStateException("Unexpected value: " + ljqType); } LjqInterface ljq = ljqMap.get(ljqStr); if(ljq!=null){ return ljq; } try{ // 支持从spring容器中取拦截器,从而支持开发在拦截器中使用spring的注解 ljq = (LjqInterface) context.getBean(ljqStr); }catch (NoSuchBeanDefinitionException t){ //没有找到,忽略 try{ Class ljqClass = Class.forName(ljqStr); try{ // 支持从spring容器中取拦截器,从而支持开发在拦截器中使用spring的注解 ljq = (LjqInterface) context.getBean(ljqClass); }catch (Throwable t1){ // 实例化定制拦截器 ljq = (LjqInterface) ljqClass.getConstructor().newInstance(); } } catch (ClassNotFoundException e) { //没找类 return null; } catch (Exception e) { slog.error("拦截器实例化失败:"+e.getMessage(), e); throw new MyException("拦截器实例化失败:"+e.getMessage(), e); } } ljqMap.put(ljqStr,ljq); ljq.init(); return ljq; } /** * 获取需要执行的拦截器 * @param ljqType 拦截器类型,默认定制拦截器 * @param sjdx 数据对象 * @param cllx 处理类型 * @param myParams 参数对象 * @return 拦截器 * @throws NoSuchMethodException 找不到方法 */ private static LjqInterface getLjq(LjqType ljqType,SysSjglSjdx sjdx,String cllx,MyParams myParams) throws NoSuchMethodException { if(ljqType==null){ ljqType = LjqType.dzljq; } LjqInterface ljq = use(sjdx,ljqType); try { if(ljq!=null){ ljq.getClass().getMethod(cllx, MyParams.class); //该拦截器正常找到要执行的方法 //每次调用后,默认都是定制拦截器,其他场景自己设置 myParams.sys().setLjqType(LjqType.dzljq); return ljq; } }catch (NoSuchMethodException e){ //没有找到该方法 } switch (ljqType){ case dzljq: return getLjq(LjqType.dzmrlqj,sjdx,cllx,myParams); case dzmrlqj: return getLjq(LjqType.kjmrljq,sjdx,cllx,myParams); case kjmrljq: throw new NoSuchMethodException("没有找到合适的拦截器"); } return ljq; } /** * 获取数据对象基础信息
* @param id 数据对象id * @return 基础信息 * @author jingma */ public static MyParams jcxxById(String id) { return jcxxById(id,null); } /** * 获取数据对象基础信息
* @param id 数据对象id * @return 基础信息 * @author jingma */ public static MyParams jcxxById(String id, SysQxYhxx user) { MyParams myParams = new MyParams(); myParams.sjdx().setId(id); return jcxxByParams(myParams,user); } /** * 获取数据对象基础信息
* @param dxdm 数据对象代码 * @return 基础信息 * @author jingma */ public static MyParams jcxxByDxdm(String dxdm) { return jcxxByDxdm(dxdm,null); } public static MyParams jcxxByDxdm(String dxdm, SysQxYhxx user) { MyParams myParams = new MyParams(true); myParams.sjdx().setDxdm(dxdm); return jcxxByParams(myParams,user); } /** * 获取数据对象基础信息
* @param authCode 数据对象代码 * @return 基础信息 * @author jingma */ public static MyParams jcxxByAuthCode(String authCode) { return jcxxByAuthCode(authCode,null); } public static MyParams jcxxByAuthCode(String authCode, SysQxYhxx user) { MyParams myParams = new MyParams(true); myParams.sys().setAuthCode(authCode); return jcxxByParams(myParams,user); } public static MyParams jcxxByParams(MyParams myParams, SysQxYhxx user) { return jcxxByParams(myParams,user,true); } /** * 自定义参数获取对象信息-内部调用 * @param myParams 自定义参数 * @param user 用户信息 * @return 对象参数 */ public static MyParams jcxxByParams(MyParams myParams, SysQxYhxx user, boolean nbdy) { if(!myParams.containsKey(LjqInterface.KEY_YOBJ)){ myParams.put(LjqInterface.KEY_YOBJ,new JSONObject()); } myParams.sys().setNbdy(nbdy); //设置请求id myParams.sys().setQqid(StringUtil.getUUIDUpperStr()); if(isBlank(myParams.sys().getCllx())){ myParams.sys().setCllx(Cllx.dxjcxx.name()); } if(myParams.other().getYsParams()==null){ //此处一般是内部调用场景,自动设置基础参数备份 myParams.other().setYsParams(JsonUtil.clone(myParams)); } if(user!=null){ myParams.put(KEY_USER,user); } return initSjdx(myParams); } /** * 数据处理
* @param myParams 相关参数 * @return 基础信息 * @author jingma */ public static Result data(MyParams myParams) { return data(myParams,myParams.sjdx(),myParams.sys().getCllx(),myParams.sys().getLjqType()); } /** * 数据处理
* @param myParams 相关参数 * @return 基础信息 * @param ljqType 拦截器类型 * @author jingma */ public static Result data(MyParams myParams,LjqType ljqType) { return data(myParams,myParams.sjdx(),myParams.sys().getCllx(),ljqType); } /** * 数据处理
* @param myParams 相关参数 * @param cllx 处理类型 * @return 基础信息 * @author jingma */ public static Result data(MyParams myParams,String cllx) { return data(myParams,myParams.sjdx(),cllx,myParams.sys().getLjqType()); } /** * 数据处理
* @param myParams 相关参数 * @param cllx 处理类型 * @param ljqType 拦截器类型 * @return 基础信息 * @author jingma */ public static Result data(MyParams myParams,String cllx,LjqType ljqType) { return data(myParams,myParams.sjdx(),cllx,ljqType); } /** * 数据处理
* @param myParams 相关参数 * @param sjdx 数据对象 * @param cllx 处理类型 * @param ljqType 拦截器类型 * @return 基础信息 * @author jingma */ public static Result data(MyParams myParams,SysSjglSjdx sjdx,String cllx,LjqType ljqType) { if(myParams.sys().getHdcst()!=null&&!(myParams.sys().getHdcst() instanceof HdInterface)){ //有回调参数体,且不是回到方法,采用异步方式 ThreadPool.use().run(()->{ try { LjqManager.setMyParams(myParams); log.debug("异步请求结束:{}",data1(myParams,sjdx,cllx,ljqType)); }catch (Throwable t){ log.warn("异步请求异常",t); }finally { LjqManager.setMyParams(null); } }); return success("异步请求成功,后续会采用回调方式返回结果数据"); } //备份原有的参数对象,此处主要是考虑内部调用时,避免相互影响 MyParams yMyParams = LjqManager.getMyParams(); LjqManager.setMyParams(myParams); Result r = data1(myParams,sjdx, cllx,ljqType); //还原参数对象 LjqManager.setMyParams(yMyParams); return r; } private static Result data1(MyParams myParams, SysSjglSjdx sjdx, String cllx, LjqType dzljq) { if(!isBlank(myParams.other().getYsParams())&&!Arrays.asList(Cllx.initSjdx.name(), Cllx.getUser.name(),Cllx.dxjcxx.name()).contains(cllx)){ Sys ysSys = myParams.other().getYsParams().sys(); if(!isBlank(ysSys.getCtqapp())&&!Conf.getAppdm() .equals(ysSys.getCtqapp())){ myParams.sys().setCtapp(ysSys.getCtqapp()); ysSys.setCtqapp(null); return data1(myParams,sjdx,Cllx.ctapp.name(), LjqType.dzljq); }else if(!isBlank(ysSys.getCtdy())){ ysSys.setCtdy(null); return data1(myParams,sjdx,Cllx.ctdy.name(), LjqType.dzljq); }else if(!isBlank(ysSys.getCtapp())&&!Conf.getAppdm() .equals(ysSys.getCtapp())){ //有穿透app,且不是当前app ysSys.setCtapp(null); return data1(myParams,sjdx,Cllx.ctapp.name(), LjqType.dzljq); } } try{ //支持通过参数设置不走定制拦截器,以适应定制调用默认的需求 LjqInterface ljq = getLjq(dzljq, sjdx, cllx,myParams); Method m = ljq.getClass().getMethod(cllx, MyParams.class); log.trace("开始执行方法:{}",cllx); if(m.getAnnotation(MyTransactional.class)!=null||m.getAnnotation(Transactional.class)!=null){ //没管事务的其他参数 DSTransactionManager.start(); try { Object r = m.invoke(ljq, myParams); log.trace("结束执行方法-事务:{},{}",cllx,r); return swtj((Result) r); }catch (Throwable e){ //回滚事务 swtj(failed("失败")); if(MyException.class.isAssignableFrom(e.getClass())){ throw e; }else if(e.getCause()!=null&&(e.getCause() instanceof MyException)){ throw (MyException)e.getCause(); }else { throw new MyException("执行失败-事务:"+cllx,e.getCause()); } } }else { return (Result) m.invoke(ljq, myParams); } } catch (NoSuchMethodException e){ //没有找到该处理类型对应的方法,执行默认操作 String zxcz = myParams.sys().getZxcz(); if(isBlank(zxcz)||Cllx.getdata.name().equals(zxcz)){ return data1(myParams,sjdx,Cllx.getdata.name(), LjqType.dzljq); }else if(Cllx.plcl.name().equals(zxcz)){ return data1(myParams,sjdx,Cllx.plcl.name(), LjqType.dzljq); }else if(Cllx.getfile.name().equals(zxcz)){ return data1(myParams,sjdx,Cllx.getfile.name(), LjqType.dzljq); }else{ throw new MyException("暂不支持的执行操作:"+zxcz); } } catch (InvocationTargetException | IllegalAccessException e) { if(e.getCause()!=null&&(e.getCause() instanceof MyException)){ throw (MyException)e.getCause(); } throw new MyException(cllx+"方法执行失败",e.getCause()); } } /** * 获取基础信息 * * @param myParams 相关参数 */ public static MyParams initSjdx(MyParams myParams) { MyParams r = (MyParams) data(myParams, xndx, Cllx.initSjdx.name(), myParams.sys().getLjqType()).getData(); myParams.sys().setLjqType(LjqType.dzljq); return r; } /** * 获取数据对象基础信息
* * @param myParams 相关参数 * @return 基础信息 * @author jingma */ public static MyParams jcxx(MyParams myParams) { return (MyParams) data(myParams,Cllx.jcxx.name()).getData(); } /** * 文件上传
* @param myParams 相关参数 * @param files 文件列表 * @return 基础信息 * @author jingma */ public static Result upload(MyParams myParams,MultipartFile[] files) throws Exception { SysSjglFile yobj = myParams.yobj(SysSjglFile.class); MyParams mp; Result r; List list = new ArrayList<>(); Result result = success("", list); for (MultipartFile file : files) { yobj.setWjm(file.getOriginalFilename()); yobj.setWjnr(Base64.getEncoder().encodeToString(file.getBytes())); mp = JsonUtil.clone(myParams); mp.put(KEY_YOBJ,yobj); r = data(mp); if (!r.isStatus()) { return r; } result.setMsg(r.getMsg()); list.add(r.getData()); } if(list.size()>1){ result.setMsg("上传成功" + files.length + "个文件"); } return result; } /** * 验证规则
* @param myParams 相关参数 * @author jingma */ public static Result yzgz(MyParams myParams) { return data(myParams,Cllx.yzgz.name()); } /** * 获取用户
* @param myParams 相关参数 * @author jingma */ public static SysQxYhxx getUser(MyParams myParams) { return data(myParams,Cllx.getUser.name()).getData(SysQxYhxx.class); } /** * 分页查询
* * @param myParams 相关参数 * @return 基础信息 * @author jingma */ public static Result select(MyParams myParams) { return data(myParams,Cllx.select.name()); } public static Result insert(MyParams myParams){ return data(myParams,Cllx.insert.name()); } public static Result update(MyParams myParams) { return data(myParams,Cllx.update.name()); } public static Result save(MyParams myParams) { return data(myParams,Cllx.save.name()); } /** * 获取sql
* * @param myParams 相关参数 * @return 0:数据载体,1:sql * @author jingma */ public static String[] getSql(MyParams myParams) { return (String[]) data(myParams,Cllx.getSql.name()).getData(); } /** * 获取sql
* * @param myParams 相关参数 * @param cllx 相关参数 * @return 0:数据载体,1:sql * @author jingma */ public static String[] getSql(MyParams myParams,String cllx) { myParams.sql().setCllx(cllx); return getSql(myParams); } /** * 结果发送到前端 * @param myParams 相关参数 * @param r 结果 */ public static void sendResult(MyParams myParams, Result r) { if(myParams==null){ myParams = new MyParams(); } myParams.put(KEY_YOBJ,r); try { data(myParams,Cllx.sendResult.name()); }catch (Throwable t){ slog.error("结果处理失败",t); r.addMsg("结果处理失败:"+t.getMessage()); myParams.put(KEY_SJDX,xndx); data(myParams,Cllx.sendResult.name()); } } /** * 流式查询 * @param sql 要执行的sq,非默认数据载体则在sql后追加;ds=xxx * @param pageSize 分页大小 * @param hdff 回调方法 * @return 执行结果 */ public static Result streamSelect(String sql, int pageSize, HdInterface hdff){ return streamSelect(sql,pageSize,hdff,6000000,null); } /** * 流式查询 * @param sql 要执行的sq,非默认数据载体则在sql后追加;ds=xxx * @param pageSize 分页大小 * @param hdff 回调方法 * @param timeout 超时时长,默认6000000 * @param ctapp 穿透的app * @return 执行结果 */ public static Result streamSelect(String sql,int pageSize,HdInterface hdff,int timeout,String ctapp){ MyParams myParams = new MyParams(); myParams.sjdx().setDxdm("SYS_COMMON_XNDX"); myParams.sys().setCllx(Cllx.select.name()); myParams.page().setTotalRequired(true); myParams.sys().setCtapp(ctapp); myParams.znjh().setSql(sql); myParams.page().setPageSize(pageSize); myParams.sys().setTimeout(timeout); //内部调用 MyParams jcxx = LjqManager.jcxxByParams(myParams, UserManager.findUser(valByDef(Conf.getUtilConfig().getZnjh().getUser(), UtilConst.SYS))); jcxx.sys().setHdcst(hdff); return LjqManager.data(jcxx,Cllx.select.name()); } /** * 远程sql执行 * @param sjzt 要执行的数据载体 * @param sql 要执行的sql * @param ctapp 要穿透的应用 * @return 执行结果 */ public static Result ycSqlExecute(String sjzt,String sql,String ctapp){ return ycSqlExecute(sjzt,sql,ctapp,600000); } /** * 远程sql执行 * @param sjzt 要执行的数据载体 * @param sql 要执行的sql * @param ctapp 要穿透的应用 * @param timeout 超时时长,默认600000 * @return 执行结果 */ public static Result ycSqlExecute(String sjzt,String sql,String ctapp,Integer timeout){ return ycSqlExecute(sjzt,sql,ctapp,timeout,null); } /** * 远程sql执行 * @param sjzt 要执行的数据载体 * @param sql 要执行的sql * @param ctapp 要穿透的应用 * @param timeout 超时时长,默认600000 * @param zxfs 处理方式,可以是select、update,默认自动根据sql识别 * @return 执行结果 */ public static Result ycSqlExecute(String sjzt,String sql,String ctapp,Integer timeout,String zxfs){ JSONObject yobj = new JSONObject(); yobj.put("sjzt",sjzt); yobj.put("zxsql",sql); yobj.put("zxfs",zxfs); //内部调用 return fwdy(ctapp,"SYS_TYGJ_SQLZX",Cllx.insert.name(), yobj,timeout); } /** * 服务调用 * @param ctapp 穿透APP * @param dxdm 对象代码 * @param cllx 处理类型 * @param yobj 原参数 * @return 调用结果 */ public static Result fwdy(String ctapp,String dxdm,String cllx,JSONObject yobj){ return fwdy(ctapp,dxdm,cllx,yobj,null); } /** * 服务调用 * @param ctapp 穿透APP * @param dxdm 对象代码 * @param cllx 处理类型 * @param yobj 原参数 * @param timeout 请求超时时间 * @return 调用结果 */ public static Result fwdy(String ctapp,String dxdm,String cllx,JSONObject yobj,Integer timeout){ MyParams myParams = new MyParams(); myParams.sjdx().setDxdm(dxdm); myParams.sys().setCllx(cllx); myParams.sys().setCtapp(ctapp); myParams.put(KEY_YOBJ,yobj); myParams.sys().setTimeout(timeout); return fwdy(myParams); } /** * 服务调用 */ public static Result fwdy(MyParams myParams){ //内部调用 MyParams jcxx = LjqManager.jcxxByParams(myParams, valByDef(myParams.user(), UserManager.findUser(valByDef(Conf.getUtilConfig().getZnjh().getUser(),UtilConst.SYS)))); return LjqManager.data(jcxx,myParams.sys().getCllx()); } /** * 内部上传文件 * @param file 文件对象 * @param user 用户信息 * @return 结果 */ public static SysSjglFile upload(SysSjglFile file,SysQxYhxx user){ MyParams jcxx = LjqManager.jcxxByAuthCode(SysAuth.QTQX.name(),user); jcxx.put(KEY_YOBJ, file); jcxx.sys().setCllx(Cllx.upload.name()); return LjqManager.data(jcxx,Cllx.upload.name()).getData(SysSjglFile.class); } public static HttpServletResponse getHttpServletResponse() { return httpServletResponseITL.get(); } public static void setHttpServletResponse(HttpServletResponse httpServletResponse) { httpServletResponseITL.set(httpServletResponse); } public static HttpServletRequest getHttpServletRequest() { return HttpServletRequestITL.get(); } public static void setHttpServletRequest(HttpServletRequest httpServletRequest) { HttpServletRequestITL.set(httpServletRequest); } }