1.开发团队有多少人
    后端开发2个人 前端开发1人 测试工程师1人 运维工程师1人

    2.系统的开发周期,运行了多长时间,数据量多大
    从立项到上线用了2个月时间,目前一直在使用,使用了有3个月左右,使用期间每日新增5000条数据左右,系统的数据达到了GB级

    3.你在你们团队中担任了什么角色
    java后端开发工程师

    4.你觉得系统中哪些技术是亮点
    a.系统的异步操作日志记录 @Log
    操作日志的记录是通过AOP+自定义注解的方式获得的
    在我们的系统中定义了一个Log注解
    该注解标记在Contrller接口的方法上,通过切面的方式记录日志,在方法返回和抛异常的时候执行
    会基于方法上注解的参数有操作类型( insert update select等)模块名称等在AOP切面中构建操作日志的实体类
    基于request中的请求参数和 方法的返回值 方法抛出的异常信息 为操作日志实体类设置属性
    讲同步的同学:
    最终将该实体类添加到数据库
    讲异步的同学:
    将操作日志实体类入库的操作定义为一个TimeTask任务,将该任务交由jdk提供的一个ScheduledExecutorService(定时任务线程池)
    来执行每次会延迟10毫秒进行插入,这样就避免了系统在插入操作日志时如果出现异常了从而导致业务功能无法正常返回
    b.系统的数据权限BaseEntity params map
    我们使用的是AOP+自定义注解实现的数据权限
    首先我们支持的数据权限分配 全部数据权限,仅个人数据权限,本部门数据权限,部门及部门以下数据权限,自定义数据权限
    在我们的系统中定义了一张分配记录的表,这张表里主要记录了线索和商机关联的所属人,并且保存了部门id,所属人id和所属人用户名
    对于数据权限来说,目的就是同一个接口不同的角色看到的数据是不一样的,那么核心就是拼接sql语句
    而在我们的系统中数据权限是和角色绑定的,所以我们在角色表里新增了一个数据权限的字段,每个角色都有一个数据权限
    在处理需要进行数据权限过滤的接口时,我们自定义了一个注解标记在我们对应方法的业务层的代码上
    使用Before作为AOP方法的增强,也就是说在业务层方法的执行前会执行AOP切面里的逻辑,在AOP切面中会进行数据权限sql的拼接
    而由于我们的系统使用的是mybatis框架所以需要将拼接好的sql语句传递到xml中进行执行,在这里我们系统中所有的实体类都继承了
    一个baseEntity在这个BaseEntity中有一个Map集合,我们将拼接好的sql语句传入到这个map集合中进行保存,在mybatis的xml文件中
    我们判断这个传入对象的map集合中的数据权限的key是否为空,如果不为空则拼接在原有的sql语句后,这样查询的时候就会带上我们在
    aop切面中拼接的sql语句了。
    简要概述一下全部数据权限:
    对于全部数据权限来说不需要区分数据的所属人,所以不用拼接sql语句
    简要概述一下自定义数据权限:
    对于自定义来说 自定义的是部门,即该角色能够看到哪些部门的数据权限,这里我们使用了一张角色部门的关联表,我们在拼接sql的
    时候会去查询当前登录用户的数据权限是否是自定义,如果是自定义的,会查询出对应关联的部门id,而在我们的分配记录表里存放了
    部门的id,如果数据关联的部门id在自定义的部门id内,则表示该数据是属于该角色的应该查询出来
    简要概述一下本部门数据权限:
    系统中的用户和部门是一对多的关系,即在用户表里有一个部门id的字段,在拼接sql的时候会先将当前登录用户的部门id获取到,然后
    通过与分配记录表里的部门id比对,如果比对成功,则该数据是属于该角色的应该查询出来
    简要概述一下本部门及以下数据权限:
    在我们的部门表中,存在一个父节点路径字段,该字段的内容是当前部门的所有父节点,我们基于当前登录用户的部门id来判断
    先查询部门表里,所有包含了该用户部门id的所有部门id,拿到一个部门id的集合,基于这些部门id,再去查询分配记录表里哪些数据
    的部门id与该集合中的部门id匹配,如果匹配则证明该数据是属于当前用户的,需要查询出来
    简要概述一下仅个人数据权限:
    获取当前登录人的用户id,根据当前登录用户的用户id去查询分配记录表,分配记录表里的用户id如果与当前登录人的用户id匹配,则表示
    该数据属于当前登录人,需要查询出来
    c.策略模式的使用(基于规则自动分配)
    @ConditionalOnProperty
    d.空间换时间的点
    CommandLineRunner和PostConstruct
    e.接口资源鉴权
    首先:
    在系统中我们将所有的接口都标记了一个权限标识符,并且有一张系统目录表,该目录表里存放了系统中所有的接口以及每个
    接口对应的权限标识符,与接口上写死的权限标识符一一对应
    在登录的时候,我们会基于当前登录的用户,查询该用户对应的所有权限标识符,并且封装在这个登录用户的对象中,然后将
    该登录用户的对象存入到redis中,redis中的key为一个uuid,value就是我们当前登录对象,然后将该uuid封装到jwt中的载荷部分
    返回给前端,前端拿到这个jwt后,会将jwt存储在header中,后续发请求的时候会在请求头里将jwt发送回后端,后端在接收到
    jwt后会解析载荷中的内容,获取到这个uuid,根据uuid查询redis,拿到当前登录的用户对象,获取登录时封装到对象中的权限标识符
    集合,如果该对象的权限标识符集合包含了,接口上写死的权限标识符这个权限标识符,则表示该用户具有该接口的访问权限,
    运行访问接口,这里的校验是通过security的@PreAuthorize注解实现的,在@PreAuthorize注解里会去调用我们声明的一个方法
    在该方法中来进行判断

    5.CRM中系统中数据的流转是什么样的?
    线索转商机,商机转合同
    异常流程:
    线索 - 》 伪线索 -》线索池
    商机 - 》 伪商机 -》公海池

    6.CRM系统中有哪些角色?
    市场专员,销售专员,市场主管,销售主管,总经理,管理员

    7.CRM系统中有哪些模块?
    线索模块,商机模块,合同模块,系统模块,公共模块,统计分析模块,定时任务模块

    8.CRM系统是盈利的?
    是公司内部使用的系统,不对外使用,只对公司内部的销售人员开放 盈利主要看公司的产品

    9.CRM系统中是如何避免销售将客户带离公司的?
    我们系统中有转派的功能,可以将离职人员的所有线索和商机转派给其他的销售来进行跟进

    10.CRM系统中的线索是如何获取的,数据量有多大?1.手动录入 2.批量导入(渠道数据,广告数据)200MB 一次文件上传 1G 8G内存

    11.CRM系统中有哪些渠道,渠道数据是如何添加的
    分为线上渠道和线下渠道两种渠道,使用的是EasyExcel进行线索的批量导入

    12.现在你们公司做活动,平均获客成本大概是多少钱?200~500

    13.你们公司使用CRM系统的过程中,是否有遇到过问题,是如何解决的?
    20MB 2GB 对接 文件中台 不会设置文件上传的大小,若文件上传文件特别巨大会采用分片上传
    10G 500M 20片 并发上传

    14.CRM系统主要售卖的是什么?课程,房,车

    15.你们系统最终是如何成交客户的?

    16.CRM系统中的线索和商机是否有自动分配功能,是如何进行自动分配的
    学习java的分配到xxx部门下的xxx员工
    学习前端的分配给xxx
    意向级别为了解的分配给xxx
    我们是基于策略模式的方式实现规则

    17.CRM系统使用了哪些框架和技术
    springboot springmvc mybatis easyExcel minio redis springsecurity+jwt
    redis key:uuid value: 验证码的值
    验证码的uuid和公式的Base64图片返回给前端,前端填写验证码的时候将uuid和填写的值发给后端
    后端拿着uuid去查询redis,如果说uuid不存在说明:验证码已过期,如果说uuid存在,比对前端提交上来的内容和缓存里的内容
    如果相同则验证通过,否则验证码比对不通过

    用户信息:
    jwt token生成前将用户信息存入到redis中,生成一个uuid作为key,将Uuid的信息存入jwt的载荷之中,将jwt返回给前端
    为什么要这么做啊: 因为token一旦生成除非过期失效,否则一直生效,假如我们希望将某个用户强制下线

    活动code:空间换时间
    在做线索导入的时候,会提前将活动编号拿出来 1次 ,拿到缓存里
    在进行线索导入的时候,对比活动编号部分就不需要再去查询数据库了,以redis缓存里的空间换取代码的执行时间
    新添加了一个活动
    1.从需求层次回答,短期内并不需要同步,不会立刻获得对应活动的客户
    2.会有一个定时任务,1H刷新一次 刷新缓存 将mysql中的活动code刷新到redis中

    18.CRM中的定时任务主要是用来做什么的: 回收过期的线索或商机,回收过期的活动

    19.CRM系统中的异常是如何处理的
    我们系统中抛出的异常是RunTimeException
    我们系统当中有一个RestControllerAdvice 在这里我们捕获了系统中所有的自定义异常,这些异常都是RuntimeExcetpion 然后获取异常信息利用包装类返回给前端

    20.CRM和瑞吉外卖整合
    我们公司主要是做外卖餐饮系统的公司,公司销售的产品主要是外卖餐饮系统,受众的用户主要是各个餐厅的总经理,老板,我们公司通过
    线上线下做活动的方式来收集客户的信息这样的数据我们称之为线索数据,做活动的人员会将收集到的线索数据汇总到一个Excel表中,统一交由
    主管在CRM系统中进行线索的导入,在我们的系统中,基于不通的餐厅类型设置了规则进行自动分配给不同的销售人员,比如:早餐店我们会分给
    xxx部门的xxx销售,西餐店我们分配给xxx销售进行,这时对应的销售人员会打电话跟进客户,了解客户对我们瑞吉外卖产品的兴趣和客户的痛点,
    针对性一对一分析,如果客户有意向,我们会将线索数据转换为一条商机,再由系统进行再次份分配,由具体的商机专员对其进行二次跟进,
    如果客户,了解客户的营业情况,位置以及能够接受的经营的范围,如何客户对我们的产品有意向,我们会和客户鉴定合同,签订合同后
    我们会安排专门的运营人员上门为客户部署我们的瑞吉外卖系统