[完结14章]Flink 从0到1实战实时风控系统

kaidnxhd2023 · · 398 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
[完结14章]Flink 从0到1实战实时风控系统 网盘地址:https://pan.baidu.com/s/1gHz7xsniPotnoL6oVFyGmA 提取码:hf2e 腾讯微云下载地址:https://share.weiyun.com/zUoCBRio 密码:dc5hxc 对于程序化交易用户而言,无论是证券还是期货市场,每一个交易指令都需要进行充分的业务检查,通过后才能进入交易所的订单队列进行匹配成交。 在程序化交易中,除了验资、验持仓等基础的风控检查外,符合交易所异常交易管理办法规定的监管标准,杜绝和防范异常交易行为也是程序化交易风控的重中之重,比如是否存在自成交、日内过度交易、频繁报撤单、大额报撤单、报单流速控制等情况。 事前风控是指在交易指令发送到交易所前,对交易指令进行风险检测,通过检测的交易指令则提交到交易模块进行报单,未通过检测的交易指令将直接予以拒绝。对于追求低延时的交易策略,事前风控需要在极短的时间内完成。 风控系统是用来给业务风控定义风控规则的,风控规则经过规则引擎的解析得到结果,表示规则是否命中,如果命中需要触发什么样的处置。 例如,业务风控定义了一个风控规则a+b>5,在规则引擎上执行的时候需要知道a,b的值,这两个值的获取一般需要通过大数据获得,然后在规则引擎上执行,从而得到结果是否命中,以及执行命中后的操作。 下面我们给内容区添加Tab标签。用户点击标签,就可以切换不同的面板内容。 <div class="site-content__wrapper"> <main class="site-content"> <el-tabs> <el-tab-pane label="标签1" name="Tab_1"> <el-card> <h1>HelloWorld</h1> </el-card> </el-tab-pane> <el-tab-pane label="标签2" name="Tab_2"> <el-card> <h1>你好世界</h1> </el-card> </el-tab-pane> </el-tabs> </main> </div> 鉴权类是需要我们自己实现的,必须要扩展StpInterface接口才可以。在com.example.his.api.config.sa_token包中,创建StpInterfaceImpl.java类。 package com.example.his.api.config.sa_token; import cn.dev33.satoken.stp.StpInterface; import com.example.his.api.db.dao.UserDao; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.Set; @Component public class StpInterfaceImpl implements StpInterface { @Resource private UserDao userDao; /** * 返回一个用户所拥有的权限集合 */ @Override public List<String> getPermissionList(Object loginId, String loginType) { List<String> list = new ArrayList<>(); int userId = Integer.parseInt(loginId.toString()); Set<String> set = userDao.searchUserPermissions(userId); list.addAll(set); return list; } /** * 返回一个用户所拥有的角色标识集合 */ @Override public List<String> getRoleList(Object loginId, String loginKey) { ArrayList<String> list = new ArrayList(); return list; } } 由于MIS系统中的权限是固定的,而角色是可以动态增减的。如果我们用@SaCheckRole注解,规定访问Web方法的用户必须具备什么角色。如果将来该角色被删除掉,难道我们还要修改大量的Web方法注解吗?就像下面的Web方法,如果角色1被删除,难不成还要让程序员重新修改代码,重新打包程序,重新发布项目吗? @RestController("MisAppointmentController") @RequestMapping("/mis/appointment") public class AppointmentController { @Resource private AppointmentService appointmentService; @PostMapping("/searchByPage") @SaCheckRole(value = {"超级管理员", "部门经理", "角色1"}, mode = SaMode.OR) public R searchByPage(@RequestBody @Valid SearchAppointmentByPageForm form) { …… } } 仔细观察不难发现,上面的截图中标签盖住了卡片控件。为了解决这个问题,我们可以让<main>标签引用site-content--tabs样式。但是也不是所有的内容页面都需要有Tab标签,比如说Home页面就不需要Tab标签栏,所以我们要用表达式切换CSS样式。 <div class="site-content__wrapper"> <main class="site-content" :class="{ 'site-content--tabs': true }"> <el-tabs> <el-tab-pane label="标签1" name="Tab_1"> <el-card> <h1>HelloWorld</h1> </el-card> </el-tab-pane> <el-tab-pane label="标签2" name="Tab_2"> <el-card> <h1>你好世界</h1> </el-card> </el-tab-pane> </el-tabs> </main> </div> 为了测试路由标签是否可以引用其他内容页面,我们不妨创建三个Vue页面试试。在/src/views/mis目录中创建home.vue、dept.vue和role.vue页面,页面视图层的标签可以随便写,只要能区分开三个页面即可。 //计算网页可见区域的高度 function resetDocumentClientHeight() { //获取网页可见区域的高度 siteContent.documentClientHeight = document.documentElement.clientHeight; } //计算内容区卡片控件高度 function loadSiteContentViewHeight() { //卡片控件高度 = 网页可见区域高度 - 导航区高度 - 卡片控件上下外填充 - 上下边框 let height = siteContent.documentClientHeight - 50 - 30 - 2; if (route.meta.isTab) { //如果引用的Vue页面需要Tab控件,卡片控件高度还要减去40 height -= 40; } //保存卡片控件高度 siteContent.height = height //声明CSS样式 siteContent.siteContentViewHeight = { minHeight: height + 'px' }; } //浏览器尺寸发生变化的回调函数 window.onresize = () => { //更新保存的网页可见区域高度 siteContent.documentClientHeight = document.documentElement.clientHeight; //重新计算内容区的高度 loadSiteContentViewHeight(); }; 具体说来风控系统由以下部分组成: 规则:风控规则定义,是由因子和操作符组成的布尔表达式,例如a+b>5 因子:风控规则的最小组成部分,例如规则a+b>5中的a,b为因子 检查点:定义外部系统和风控系统的对接关系,例如用户中心在用户注册的时候需要调用风控系统,检查点定义了外部系统的调用参数,以及需要运行哪些规则。 数据源:提供因子数据,例如规则a>5表示的业务含义为用户连续登录失败次数大于5次,用户连续登录失败次数作为因子a,a的数据来源通过数据源来提供。数据源是对因子来源的抽象。 <div class="site-content__wrapper"> <main class="site-content" :class="{ 'site-content--tabs': $route.meta.isTab }"> <el-tabs v-if="$route.meta.isTab" v-model="siteContent.mainTabsActiveName" :closable="true"> <el-tab-pane v-for="item in siteContent.mainTabs" :label="item.title" :name="item.name"> <el-card :body-style="siteContent.siteContentViewHeight"> <router-view :key="router.currentRoute.value.query.random" /> </el-card> </el-tab-pane> </el-tabs> <el-card v-else :body-style="siteContent.siteContentViewHeight"> <router-view :key="router.currentRoute.value.query.random" /> </el-card> </main> </div> 我们先给框架页面<el-tabs>标签添加事件处理。其中@tab-click捕获的是切换Tab标签事件;@tab-remove捕获的是关闭Tab标签事件。 <div class="site-content__wrapper"> <main class="site-content" :class="{ 'site-content--tabs': $route.meta.isTab }"> <el-tabs v-if="$route.meta.isTab" v-model="siteContent.mainTabsActiveName" :closable="true" @tab-click="selectedTabHandle" @tab-remove="removeTabHandle"> <el-tab-pane v-for="item in siteContent.mainTabs" :label="item.title" :name="item.name"> <el-card :body-style="siteContent.siteContentViewHeight"> <router-view :key="router.currentRoute.value.query.random" /> </el-card> </el-tab-pane> </el-tabs> <el-card v-else :body-style="siteContent.siteContentViewHeight"> <router-view :key="router.currentRoute.value.query.random" /> </el-card> </main> </div> 在框架页面的模型层中,定义removeTabHandle()封装函数。 function removeTabHandle(tabName) { //让mainTabs数组剔除要关闭的Tab siteContent.mainTabs = siteContent.mainTabs.filter(item => item.name !== tabName); //如果还存在剩余的Tab,就切换到最后的Tab上面 if (siteContent.mainTabs.length >= 1) { //获取mainTabs数组最后一个元素 let tab = siteContent.mainTabs[siteContent.mainTabs.length - 1]; //选中这个Tab控件 siteContent.mainTabsActiveName = tab.name; //内容区切换引用的页面 router.push({ name: tab.name }); } else { siteContent.mainTabsActiveName = ''; router.push({ name: 'MisHome' }); } } 其实也不是所有的Web方法或者HTML页面都需要用户登陆之后才能访问,比如登陆页面和对应的后端Web方法。但是有些Web方法必须用户登陆之后才能访问,我们可以给Web方法添加@SaCheckLogin注解。这个注解会拦截Web方法的请求,让SaToken验证客户端提交的Token令牌。如果令牌合法就允许调用Web方法,反之就拒绝HTTP请求,返回401状态码。 @RestController @RequestMapping("/mis/user") public class UserController { …… @GetMapping("/searchUserSummary") @SaCheckLogin public R searchUserSummary() { …… } }
398 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传