网站首页> 博客> 基于SSM框架CRM客户管理系统
基于SSM框架CRM客户管理系统
1、概述
-
开发环境
IDE: Myeclipse
Jdk: 1.8
数据库: MySQL
在线演示:CRM客户关系管理系统
账号:admin
密码:123456
1.1 目的
客户关系管理系统通过对客户生命周期的有效管理,帮助企业有效管理客户资源、控制销售过 程、缩短销售周期、提高销售成功率;通过对客户相关信息的分析与挖掘,识别客户消费规律 和客户价值,指导企业的部门运作和市场规划,从而提供更加快捷和周到的优质服务,帮助企 业提升客户满意度和忠诚度,最终提高企业市场竞争力。
2、任务概述
2.1 开发背景
伴随着CRM客户管理系统在国内的飞速发展,绝大部分的企业都在应用CRM系统来服务自个 的企业,而且取得显著效果,CRM系统强调建立一个以客户为中心的现代企业,以客户价值来 判定市场的需求,满足了将企业的战略从以产品为中心转向以客户为中心的企业需求。应用 CRM最终达到提高企业客户的满意度,减少客户的流失。
3、系统简介
CRM客户关系管理是企业通过提供创新式的个性化客户服务为招揽新客户、保留旧客户、更好 的提供客户服务以及进一步培养企业和客户之间的关系、提升客户忠诚度的利用信息技术来协 调公司与客户间的销售、服务的营销管理方式。
4、业务需求描述
业务类别 |
子业务 |
业务详解 |
基础模块 |
用户登录 |
用户登录 |
退出 |
退出当前登录用户 |
|
记住密码 |
记住登录用户的账号密码 |
|
密码修改 |
修改密码 |
|
... |
其他 |
|
营销管理模块 |
营销机会管理: |
企业客户的质询(询问)需求所建立的信息录入功能 |
客户开发计划 |
开发计划是根据营销机会而来,对于企业质询的客户, 会有相应的销售人员对于该客户进行具体的沟通交流,此时对于整个 CRM系统而言,通过营销开发计划来进行相应的信息管理,提高客户 的购买企业产品的可能性。 |
|
… |
||
客户管理模块 |
客户信息管理 |
CRM系统中完整记录客户信息来源的数据、企业与 客户交往、客户订单查询等信息录入功能,方便企业与客户进行相应 的信息交流与后续合作。 |
客户流失管理 |
CRM通过一定规则机制所定义的流失客户(无效客 户),通过该规则可以有效管理客户信息资源,提高营销开发的效率。 |
|
服务管理模块 |
服务管理是针对客户而开发的功能,针对客户要求,CRM提供客户 相应的信息质询,反馈与投诉功能,提高企业对于客户的服务质量。 |
服务管理是针对客户而开发的功能,针对客户要求,CRM提供客户 相应的信息质询,反馈与投诉功能,提高企业对于客户的服务质量。 |
文件中心模块 |
上传合同文件 |
文件格式要求是PDF文件,其他文件不能上传 |
查询文件 |
查询所有文件,或根据文件标题进行模糊查询 |
|
下载文件 |
文件需要提供下载功能 |
|
系统公告模块 |
发布公告 |
发布系统公告 |
删除公告 |
删除公告 |
|
公告列表 |
列出全部公告 |
5、业务描述
5.1 基础模块
(一)登录
1)业务描述
提供用户登录的功能,登录之后,可以进入主菜单进行操作其他菜单
2)输入
账号 |
不低于4位的英文单词组成 |
密码 |
长度不低于6位,并且要有英文大写字母 |
验证码 |
先识别验证码是否正确 |
3)输出
登录成功,进行页面跳转,跳转到主页面
登录失败,进行页面的跳转,跳转到登录页面,并且提示登录失败的原因
4)业务流程
- 访问登录页面
- 在页面中输入用户名,密码信息,点击登录的按钮,提交数据
- 服务器接收到客户端的请求数据,去查询数据库
- 查询数据库之后,根据查询的结果响应前端
- 前端接受客户端的相应,并给出页面跳转到的操作
(二)退出
1)请求 删除用户登录数据
2)成功跳转到登录页面
(三)记住登录
记住当前登录用户的登录账号和密码
1)加密用户数据
2)保存到session
(四)修改密码
修改用户的登录密码
1)验证输入用户老密码是否正确
2)检查新密码是否符合规则
3)请求 修改
5.2 营销管理模块
(一)营销机会管理
增:
1)前端js验证数据是否符合规则
2)提交数据到后端进行添加处理
3)失败 成功提示并刷新数据
删:
1)根据索引删除数据
改:
1)验证数据是否符合规则
2)根据索引修改数据
查:
1)分页查询数据列出
企业客户的质询(询问)需求所建立的信息录入功能
(二)客户开发计划
开发计划是根据营销机会而来,对于企业质询的客户,
会有相应的销售人员对于该客户进行具体的沟通交流,此时对于整个
CRM系统而言,通过营销开发计划来进行相应的信息管理,提高客户
的购买企业产品的可能性。
5.3 客户管理模块
(一)客户信息管理
增:
1)验证客户数据是否符合规则
2)符合请求数据添加
删:
1)根据索引请求后端进行删除
改:
1)根据索引修改数据 请求前先前端验证
查:
1)分页查询数据列出
CRM系统中完整记录客户信息来源的数据、企业与客户交往、客户订单查询等信息录入功能,方便企业与客户进行相应的信息交流与后续合作。
(二)客户流失管理
CRM通过一定规则机制所定义的流失客户(无效客户),通过该规则可以有效管 理客户 信息资源,提高营销开发的效率。
5.4 服务管理模块
服务管理是针对客户而开发的功能,针对客户要求,CRM提供客户相应的信息质询, 反馈与投诉功能,提高企业对于客户的服务质量。
5.5 文件中心模块
(一)上传合同文件
1)验证文件格式是否是pdf
2)检测文件大小是否符合要求
1、1 上传请求
文件格式要求是PDF文件,其他文件不能上传
1、2 查询文件
1)根据用户选择的查询类型进行模糊查询 (上传时间,上传文件名)
2)查询所有文件,或根据文件标题进行模糊查询
1、3 下载文件
1)下载请求
2)输出文件下载
3)文件需要提供下载功能
5.6 系统公告模块
1、1 添加公告
1)验证公告数据是否符合规则
2)请求后端添加
1、2 删除公告
1)根据索引进行删除
1、3 公告列表
1)分页查询数据列出
6、项目部分代码
aop日志:
package com.crm.aop;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.crm.pojo.Log;
import com.crm.pojo.SessionUser;
import com.crm.service.LogService;
@Aspect //该标签把LoggerAspect类声明为一个切面
@Order(1) //设置切面的优先级:如果有多个切面,可通过设置优先级控制切面的执行顺序(数值越小,优先级越高)
@Component //该标签把LoggerAspect类放到IOC容器中
public class LoggerAspect {
@Autowired
private LogService logService;
@Autowired
private HttpServletRequest request;
/**
* 取aop返回的json文本的对应值内容
* */
private String JSONAOP(String json,String path) {
int start=json.indexOf(path);
int end=json.indexOf(",", start);
if(end==-1) {end=json.length()-1;}//last
return json.substring(start+path.length()+1,end);//+1 =
}
/**
* 快速生成一个log
* */
private Log getLog(String Type,String Content,String userId) {
Log log= new Log();
log.setIp(request.getRemoteAddr());
log.setTime(new Date());
log.setType(Type);
log.setContent(Content);
log.setUserId(userId);
return log;
}
/**
* 定义一个方法,用于声明切入点表达式,方法中一般不需要添加其他代码
* 使用@Pointcut声明切入点表达式
* 后面的通知直接使用方法名来引用当前的切点表达式;如果是其他类使用,加上包名即可
*/
@Pointcut("execution(public * com.crm.controller.*Controller.*(..))")
public void declearJoinPointExpression(){}
/**
* 前置通知
* @param joinPoint
*/
@Before("declearJoinPointExpression()") //该标签声明次方法是一个前置通知:在目标方法开始之前执行
public void beforMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
List
登录控制器 :
package com.crm.controller;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import com.crm.pojo.Marketer;
import com.crm.pojo.SessionUser;
import com.crm.pojo.WebSystem;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.crm.pojo.Admin;
import com.crm.pojo.IRole;
import com.crm.service.AdminService;
import com.crm.service.CustomerProjectService;
import com.crm.service.CustomerService;
import com.crm.service.IRoleService;
import com.crm.service.MarketerService;
import com.crm.service.NoticeService;
import com.crm.service.OrdersService;
import com.crm.service.SystemService;
import com.crm.util.CpachaUtils;
import com.crm.util.EncryptionUtil;
import com.crm.util.Interceptor;
import com.crm.util.JsonUtil;
import com.crm.util.Permission;
/**
* 系统主页控制器
* @version
*/
@Controller
@RequestMapping("/system")
public class SystemController {
@Autowired
private MarketerService marketerService;
@Autowired
private AdminService adminService;
@Autowired
private SystemService systemService;
@Autowired
private IRoleService roleService;
@Autowired
private CustomerService customerService;
@Autowired
private CustomerProjectService customerProjectService;
@Autowired
private NoticeService noticeService;
@Autowired
private OrdersService ordersService;
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(ModelAndView model,HttpServletRequest req) {
ServletContext application=req.getServletContext();
WebSystem web=(WebSystem) application.getAttribute("WebSystem");
SessionUser user = (SessionUser) req.getSession().getAttribute("SUser");
if (user != null) {
try {
if(new Interceptor().toeknVer(user)) {//验证成功给它自动跳转到首页去
if(web!=null) {
model.setView(new RedirectView( "/system/index", true, false, true ));
model.addObject("token",EncryptionUtil.getMD5(user.getToken()));
return model;
}else {System.out.println("系统错误:存在非法注入");}
//resp.sendRedirect(req.getContextPath() + "/system/index");
}
} catch (UnsupportedEncodingException e) {
req.getSession().setAttribute("SUser", null);//token验证失败了直接给他清掉
}
}
Object obj=application.getAttribute("permissionData");
if(obj==null) {//初始化api权限
application=Permission.Initialize(application);
}
/**
* 写入网站数据 方便页面直接调用 主要是为了减少服务器资源占用 当然这样就相当于了一个缓存
* */
if(application.getAttribute("WebSystem")==null) {
application.setAttribute("WebSystem", systemService.getSystem());
}
model.setViewName("system/login");
return model;
}
@RequestMapping(value = "/index", method = RequestMethod.GET)
public ModelAndView index(ModelAndView model) {
model.setViewName("system/index");
return model;
}
@RequestMapping(value = "/reg", method = RequestMethod.GET)
public ModelAndView reg(ModelAndView model) {
model.setViewName("system/reg");
return model;
}
@RequestMapping(value = "/WebSet", method = RequestMethod.GET)
public ModelAndView WebSet(ModelAndView model) {
model.addObject("Web",systemService.getSystem());
model.setViewName("system/web_set");
return model;
}
@RequestMapping(value = "/welcome", method = RequestMethod.GET)
public ModelAndView welcome(ModelAndView model) {
Map
retMap.put("customerSize",customerService.getTotal(new HashMap
retMap.put("customerProjectSize",customerProjectService.getTotal(new HashMap
retMap.put("marketerSize", marketerService.getTotal(new HashMap
retMap.put("ordersSize", ordersService.getTotal(new HashMap
Map
/**
* 倒着找数据 找最新的公告
* */
int noticeSize=noticeService.getTotal(queryMap);
if(noticeSize-10<0) {noticeSize=0;}else {noticeSize-=10;}
queryMap.put("limit", 10);
queryMap.put("offset",noticeSize);
retMap.put("noticeList",noticeService.findList(queryMap));
model.addObject("Data",retMap);
model.setViewName("system/welcome");
return model;
}
@RequestMapping(value = "/login_out", method = RequestMethod.GET)
public String loginOut(HttpServletRequest request) {
request.getSession().setAttribute("SUser", null);
return "redirect:login";
}
@RequestMapping(value = "/permission", method = RequestMethod.GET)
public ModelAndView permission(ModelAndView model,@RequestParam(name = "id", required = false) String id) {
if(id!=null && !id.equals("")) {
model.addObject("id",id);//取当前用户数据
model.setViewName("system/permission/permission");
}else {
model.setViewName("404");
}
return model;
}
@RequestMapping(value = "/permissionEdit", method = RequestMethod.GET)
public ModelAndView permissionEdit(ModelAndView model,
@RequestParam(name = "index", required = false) String index,
@RequestParam(name = "id", required = false) Long id) {
Map
客户控制器:
package com.crm.controller;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSONArray;
import com.crm.pojo.Customer;
import com.crm.service.CustomerService;
import com.crm.service.MarketerService;
import com.crm.util.ExcelUtil;
import jxl.read.biff.BiffException;
/**
* 客户控制器
*
* @date:2021年12月7日 下午4:16:06
*/
@Controller
@RequestMapping("/customer")
public class CustomerController {
@Autowired
private CustomerService customerService;
@Autowired
private MarketerService marketerService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public ModelAndView list(ModelAndView model) {
Map
model.addObject("merkList", marketerService.findList(queryMap));
model.setViewName("customer/customer_list");
return model;
}
@RequestMapping(value = "/listDrain", method = RequestMethod.GET)
public ModelAndView listDrain(ModelAndView model) {
Map
model.addObject("merkList", marketerService.findList(queryMap));
model.setViewName("customer/customerdrain_list");
return model;
}
@RequestMapping(value = "/importCustomer", method = RequestMethod.GET)
public ModelAndView importCustomer(ModelAndView model) {
Map
model.addObject("merkList", marketerService.findList(queryMap));
model.setViewName("customer/customer_import");
return model;
}
@RequestMapping(value = "/updateDrain", method = RequestMethod.GET)
public ModelAndView updateDrain(ModelAndView model, @RequestParam(name = "id", required = false) Integer id) {
Map
model.addObject("type", 1);// 前端参数类型 1表示修改
if (id != null) {
Customer customerdrain = customerService.findByCustomerId(id);
model.addObject("customerdrain", customerdrain);// 取当前用户数据
model.addObject("merkList", marketerService.findList(queryMap));
model.setViewName("customer/customerdrain_update");
} else {
model.setViewName("404");// 如未传递id直接404 因为在web.xml中设置了404 所以随便指定一个未存在页面即可 *注意并不是说serViewName(404)就代表了404的源地址
}
return model;
}
@RequestMapping(value = "/add", method = RequestMethod.GET)
public ModelAndView add(ModelAndView model) {
Map
model.addObject("merkList", marketerService.findList(queryMap));
model.setViewName("customer/customer_add_update");
model.addObject("type", 2);// 前端类型 1是修改,2是添加
return model;
}
@RequestMapping(value = "/update", method = RequestMethod.GET)
public ModelAndView update(ModelAndView model, @RequestParam(name = "id", required = false) Integer id) {
Map
model.addObject("type", 1);// 前端类型 1是修改,2是添加
if (id != null) {
Customer customer = customerService.findByCustomerId(id);
model.addObject("customer", customer);
model.addObject("merkList", marketerService.findList(queryMap));
model.setViewName("customer/customer_add_update");
} else {
model.setViewName("404");
}
return model;
}
@RequestMapping(value = "ApicustomerImportData", method = {RequestMethod.POST})
@ResponseBody
public Map
@RequestParam(name="marketerId", required = false) Integer marketerId,
@RequestParam(name="customerData", required = false) String data
) {
Map
if(marketerId!=null && marketerId!=0) {
JSONArray dataArr=(JSONArray) JSONArray.parse(data);
for(Object d:dataArr) {
JSONArray a=(JSONArray)d;
Customer customer=new Customer();
customer.setMarketerId(marketerId);
customer.setName(a.get(0).toString());
customer.setAddress(a.get(1).toString());
customer.setTel(a.get(2).toString());
customer.setMemo(a.get(3).toString());
customerService.add(customer);
}
retmap.put("code", 0);
retmap.put("msg", "导入结束");
}else {
retmap.put("code", 201);
retmap.put("msg", "请指定营销员");
}
return retmap;
}
/**
* 导入客户excel
* @return Map
* @throws Exception
*/
@RequestMapping(value = "/ApiImportExcel", method = {RequestMethod.POST})
@ResponseBody
public Map
Map
if(file!=null) {
CommonsMultipartFile cf= (CommonsMultipartFile)file;
DiskFileItem fi = (DiskFileItem)cf.getFileItem();
File excelFile = fi.getStoreLocation();
try {
String[][] data=ExcelUtil.readSpecifyRows(excelFile);
retmap.put("code",0);
retmap.put("msg","解析成功");
retmap.put("data",data);
} catch (BiffException | IOException e) {
//e.printStackTrace();
retmap.put("code", 201);
retmap.put("msg","文件错误,请提交正确的Excel文件!");
}
}else {
retmap.put("code", 201);
retmap.put("msg","请上传文件");
}
return retmap;
}
/**
* 获取客户列表
*
* @param name
* @param marketerId
* @param status
* @param limit
* @param page
* @return
*/
@RequestMapping(value = "/ApiGetList", method = RequestMethod.POST)
@ResponseBody
public Map
@RequestParam(name = "marketerId", required = false) Integer marketerId,
@RequestParam(name = "tel", required = false) String tel,
@RequestParam(name = "limit", required = false) Integer limit,
@RequestParam(name = "page", required = false) Integer page,
@RequestParam(name = "status", required = false) Integer status
) {
Map
Map
queryMap.put("name", name);
queryMap.put("marketerId", marketerId);
queryMap.put("tel", tel);
queryMap.put("offset", limit * (page - 1));// 对应数据库中的偏移量
queryMap.put("limit", limit * page);// 每页显示记录条数,也就是每页显示的数量
queryMap.put("status",status);//用户状态
List
if (!customer.isEmpty()) {
retMap.put("code", 0);// 状态码 layui中code为0才是成功 注意不是200
retMap.put("msg", "success");// msg
retMap.put("data", customer);// 数据
retMap.put("count", customerService.getTotal(queryMap));// 获取符合结果的总记录数
return retMap;
} else {
retMap.put("code", "201");
retMap.put("msg", "无数据");
return null;
}
}
/**
* 添加
*
* @param name
* @param address
* @param marketerId
* @param tel
* @param status
* @param memo
* @return
*/
@RequestMapping(value = "/ApiAdd", method = RequestMethod.POST)
@ResponseBody
public Map
Map
if (customerService.add(customer) > 0) {
retMap.put("code", 0);
retMap.put("msg", "success");
} else {
retMap.put("code", 201);
retMap.put("msg", "error");
}
return retMap;
}
/**
* 删除
*
* @param ids
* @return
*/
@RequestMapping(value = "/ApiDelete", method = RequestMethod.POST)
@ResponseBody
public Map
Map
if (ids == null) {
retMap.put("type", "error");
retMap.put("msg", "请选择要删除的数据!");
return retMap;
}
String idsString = "";
for (Long id : ids) {// 把Long分割并转换为idsString这个是加强for循环,逐个遍历ids的每个元素 直到ids的最后一个遍历完 跳出循环,
// ids大于0,也就是有多个,就把这个ids赋给数组,并循环,在循环里去数组的值,进行多个操作
idsString += id + ",";
}
idsString = idsString.substring(0, idsString.length() - 1);// 截取掉字符串的最后一位
if (customerService.delete(idsString) <= 0) {// 文本框中内容非空时执行删除操作
retMap.put("type", "error");
retMap.put("msg", "删除失败!");
return retMap;
}
retMap.put("type", "success");
retMap.put("msg", "删除成功!");
return retMap;
}
/**
* 修改
*
* @param customer
* @param request
* @param address
* @param marketerId
* @param tel
* @param memo
* @return
*/
@RequestMapping(value = "/ApiUpdate", method = RequestMethod.POST)
@ResponseBody
public Map
Map
/**
* status代表status没有经过修改的值 这里有个注意的点 因为customer里面status的类型定义的是Integer 不是int 所以必须先判断是不是为空
* 否则一旦status没有传就会空指针
* Integer的默认值为null int默认值为0
* */
if(customer.getStatus()!=null && customer.getStatus()==0 && statusRaw==1) {
customer.setLostTime(new Date());
}
if (customerService.update(customer) > 0) {
retMap.put("code", 0);
retMap.put("msg", "success");
} else {
retMap.put("code", 201);
retMap.put("msg", "修改失败");
}
return retMap;
}
}
工具类:
package com.crm.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
/**
* 加密工具类
* @date: 2021年11月3日 下午8:00:16
* @version V1.0
*/
public class EncryptionUtil {
/***
* MD5加密
* */
public static String getMD5(String strMD5) {
try {
// 得到一个信息摘要器
MessageDigest digest = MessageDigest.getInstance("md5");
byte[] result = digest.digest(strMD5.getBytes());
StringBuffer buffer = new StringBuffer();
// 把每一个byte 做一个与运算 0xff;
for (byte b : result) {
// 与运算
int number = b & 0xff;// 加盐
String str = Integer.toHexString(number);
if (str.length() == 1) {
buffer.append("0");
}
buffer.append(str);
}
// 标准的md5加密后的结果
return buffer.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return "";
}
}
/**
* RC4加解密
* */
public static String HloveyRC4(String aInput,String aKey)
{
int[] iS = new int[256];
byte[] iK = new byte[256];
for (int i=0;i<256;i++)
iS[i]=i;
int j = 1;
for (short i= 0;i<256;i++)
{
iK[i]=(byte)aKey.charAt((i % aKey.length()));
}
j=0;
for (int i=0;i<255;i++)
{
j=(j+iS[i]+iK[i]) % 256;
int temp = iS[i];
iS[i]=iS[j];
iS[j]=temp;
}
int i=0;
j=0;
char[] iInputChar = aInput.toCharArray();
char[] iOutputChar = new char[iInputChar.length];
for(short x = 0;x
i = (i+1) % 256;
j = (j+iS[i]) % 256;
int temp = iS[i];
iS[i]=iS[j];
iS[j]=temp;
int t = (iS[i]+(iS[j] % 256)) % 256;
int iY = iS[t];
char iCY = (char)iY;
iOutputChar[x] =(char)( iInputChar[x] ^ iCY) ;
}
return new String(iOutputChar);
}
/**
* base64编码
* @param string
* @return
* @throws UnsupportedEncodingException
*/
public static String Base64Encoder(String string) throws UnsupportedEncodingException {
Encoder encoder = Base64.getEncoder();
byte[] textByte = string.getBytes("UTF-8");
return encoder.encodeToString(textByte);
}
/**
* base64解码
* @param string
* @return
* @throws UnsupportedEncodingException
*/
public static String Base64Decoder(String string) throws UnsupportedEncodingException {
Decoder decoder = Base64.getDecoder();
return new String(decoder.decode(string), "UTF-8");
}
}
package com.crm.util;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.alibaba.fastjson.TypeReference;
public class JsonUtil {
/**
* json string 转换为 map 对象
*
* @param jsonObj
* @return
*/
public static Map
return JSONObject.parseObject(jsonObj.toJSONString(), new TypeReference
7、项目运行截图
(一)登录页面
(二)登录成功
(三)系统主界面
(四)网站添加
(五)权限列表
(六)项目收款(分步)(七)系统操作日志
(八)公告发布
(九)公告列表
(十)菜单列表
(十一)客户导入(Excel表)
(Excel表)
(点击导入后)
(十二)项目合同
(十三)项目收款
(十四)添加管理员
(十五)添加客户
(十六)退出
愿你有好运气,如果没有,愿你在不幸中学会慈悲;愿你被很多人爱,如果没有,愿你在寂寞中学会宽容!
- 加入微信群,不定期分享源码和经验

- 签到活跃榜 连续签到送额外金币
- 最新博客
- 校园跑腿系统外卖系统软件平台大学生创业平台搭建 859
- 壹脉销客智能名片CRM系统小程序可二开源码交付部署 883
- 为啥没搞了 1352
- Nginx 的 5 大应用场景,太实用了! 1539
- CentOS 8-stream 安装Postgresql 详细教程 1838
- JAVA智慧校园管理系统小程序源码 电子班牌 Sass 模式 1411
- Java智慧校园系统源码 智慧校园源码 智慧学校源码 智慧校园管理系统源码 小程序+电子班牌 1188
- Java智慧校园系统源码 智慧校园源码 智慧学校源码 智慧校园管理系统源码 小程序+电子班牌 1160
- 致远OA权限 1979
- 发博客会有金币吗 1216