Java 初識(shí)CRM之項(xiàng)目思路解析
CRM項(xiàng)目

一、登錄模塊全程思路分析


登錄模塊:
1、對(duì)用戶(hù)名和密碼的校驗(yàn),并存儲(chǔ)在cookie中,方便后期的免登錄操作。
2、對(duì)用戶(hù)基本信息的修改,通過(guò)獲取表單用戶(hù)修改的數(shù)據(jù),進(jìn)行Ajax請(qǐng)求,對(duì)修改之后id對(duì)應(yīng)用戶(hù)進(jìn)行數(shù)據(jù)庫(kù)信息修改
3、修改密碼,獲取用戶(hù)輸入的表單數(shù)據(jù),進(jìn)行service層校驗(yàn),判斷原密碼,新密碼確認(rèn)密碼,最后對(duì)數(shù)據(jù)庫(kù)用戶(hù)密碼進(jìn)行修改
4、每次修改信息后會(huì)自動(dòng)清楚cookie內(nèi)的數(shù)據(jù),退出重新登錄
5、service層會(huì)調(diào)用很多工具類(lèi)提供便潔業(yè)務(wù)處理
⭐核心代碼
controller層UserController.java
@Controller
@RequestMapping("user")
public class UserController extends BaseController {
@Autowired
UserService userService;
//修改密碼頁(yè)面跳轉(zhuǎn)
@RequestMapping("toPasswordPage")
public String updatePwd(){
return "user/password";
}
//登錄
@RequestMapping("login")
@ResponseBody
public ResultInfo login(User user){
ResultInfo result=new ResultInfo();
try{
//捕獲異常
UserModel userModel=userService.userLogin(user.getUserName(),user.getUserPwd());
//登錄成功
result.setCode(200);
result.setMsg("登錄成功~");
result.setResult(userModel);
}catch (ParamsException ex){
ex.printStackTrace();
result.setCode(ex.getCode());
result.setMsg(ex.getMsg());
}catch (Exception e){
e.printStackTrace();
result.setCode(500);
result.setMsg("操作失敗~");
}
return result;
}
/*修改密碼*/
@PostMapping("updatePwd")
@ResponseBody
public ResultInfo updatePwd(HttpServletRequest req,String oldPwd,String newPwd,String againPwd){
ResultInfo result=new ResultInfo();
//獲取cookie獲取用戶(hù)ID
int userId=LoginUserUtil.releaseUserIdFromCookie(req);
userService.updatePwd(userId,oldPwd,newPwd,againPwd);
return result;
}
}
Service層UserService.java
@Service
public class UserService extends BaseService<User,Integer> {
@Resource
UserMapper userMapper;
/*用戶(hù)登錄*/
public UserModel userLogin(String userName,String userPwd){
//判斷用戶(hù)名和密碼是否為空
checkNull(userName,userPwd);
//檢查是否已經(jīng)存在
User user=userMapper.selectByuserName(userName);
AssertUtil.isTrue(user==null,"用戶(hù)名不存在!");
//檢查密碼
checkPwd(userPwd,user.getUserPwd());
return buildInfo(user);
}
//設(shè)置返回信息
private UserModel buildInfo(User user) {
UserModel um=new UserModel();
um.setUserName(user.getUserName());
um.setUserId(UserIDBase64.encoderUserID(user.getId()));//對(duì)ID加密
um.setTrueName(user.getTrueName());
return um;
}
//密碼驗(yàn)證
private void checkPwd(String userPwd, String userPwd1) {
String enPwd=Md5Util.encode(userPwd);
AssertUtil.isTrue(!enPwd.equals(userPwd1),"密碼不正確!");
}
//判斷是否為空
private void checkNull(String userName,String userPwd){
//判斷用戶(hù)名和密碼是否為空
AssertUtil.isTrue(StringUtils.isBlank(userName),"用戶(hù)名不能為空!");
AssertUtil.isTrue(StringUtils.isBlank(userPwd),"用戶(hù)密碼不能為空!");
}
/*修改密碼*/
public void updatePwd(int userId,String oldPwd,String newPwd,String againPwd){
//通過(guò)id獲取用戶(hù)
System.out.println(userId);
User user=userMapper.selectByPrimaryKey(userId);
System.out.println(user);
//檢驗(yàn)并修改密碼
isOkForPwd(user,oldPwd,newPwd,againPwd);
//修改密碼
user.setUserPwd(Md5Util.encode(newPwd));
//修改數(shù)據(jù)庫(kù)內(nèi)容
AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user)<1,"操作失敗");
}
//檢驗(yàn)密碼
private void isOkForPwd(User user, String oldPwd, String newPwd, String againPwd) {
//判斷用戶(hù)是否為空
AssertUtil.isTrue(user==null,"用戶(hù)未登錄或不存在!");
//原密碼是否為空
AssertUtil.isTrue(StringUtils.isBlank(oldPwd),"原密碼不能為空!");
//新密碼判斷是否為空
AssertUtil.isTrue(StringUtils.isBlank(newPwd),"新密碼不能為空!");
//對(duì)原密碼判斷是否正確
AssertUtil.isTrue(!(user.getUserPwd().equals(Md5Util.encode(oldPwd))),"原密碼不正確!");
//對(duì)新密碼和原密碼進(jìn)行判斷
AssertUtil.isTrue(oldPwd.equals(newPwd),"原密碼和新密碼不能一致!");
//對(duì)再次輸入判斷是否為空
AssertUtil.isTrue(StringUtils.isBlank(againPwd),"二次驗(yàn)證密碼不能為空!");
//判斷新密碼與二次輸入
AssertUtil.isTrue(!(newPwd.equals(againPwd)),"新密碼與第二次輸入不一致!");
}
}
全局異常具體代碼:GlobalExceptionResolver.java
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) {
//登錄異常處理
if(ex instanceof NoLoginException){
// 如果捕獲的是未登錄異常,則重定向到登錄頁(yè)面
ModelAndView mv = new ModelAndView("redirect:/index");
return mv;
}
//實(shí)例化ModelandView 異常則跳轉(zhuǎn)error
ModelAndView mv=new ModelAndView("error");
mv.addObject("code",400);
mv.addObject("msg","系統(tǒng)異常~");
if(handler instanceof HandlerMethod){
//則返回頁(yè)面
HandlerMethod hm=(HandlerMethod) handler;
//通過(guò)反射獲取注解@responseBody對(duì)象
ResponseBody resquestBody=hm.getMethod().getDeclaredAnnotation(ResponseBody.class);
//判斷是否被注解
if(resquestBody==null){
//返回頁(yè)面
if(ex instanceof ParamsException){
ParamsException param=(ParamsException) ex;
//設(shè)置
mv.addObject("code",param.getCode());
mv.addObject("msg",param.getMsg());
}
}else{
//返回json
ResultInfo result=new ResultInfo();
result.setCode(300);
result.setMsg("系統(tǒng)異常~");
//異常處理
if(ex instanceof ParamsException){
ParamsException param=(ParamsException) ex;
//設(shè)置
result.setCode(param.getCode());
result.setMsg(param.getMsg());
// 設(shè)置響應(yīng)類(lèi)型和編碼格式 (響應(yīng)JSON格式)
resp.setContentType("application/json;charset=utf-8");
//通過(guò)數(shù)據(jù)流寫(xiě)出
PrintWriter out= null;
try {
out = resp.getWriter();
out.write(JSON.toJSONString(result));
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
out.close();
}
}
return null;
}
}
}
return mv;
}
}
攔截器NoLoginInterceptor.java
public class NoLoginInterceptor extends HandlerInterceptorAdapter {
@Resource
UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//根據(jù)cookie中id值登錄攔截
//獲取cookie用戶(hù)id
Integer userId = LoginUserUtil.releaseUserIdFromCookie(request);
if(userId==null || userService.selectByPrimaryKey(userId)==null){
throw new NoLoginException("未登錄異常~");
}
return true;
}
}
dao層與mappers映射層直接生成,其余靜態(tài)頁(yè)面和素材略....(詳情代碼看上傳資源)
二、營(yíng)銷(xiāo)模塊全程思路分析



營(yíng)銷(xiāo)模塊:
1、主要進(jìn)行營(yíng)銷(xiāo)機(jī)會(huì)的添加、刪除、編輯
2、首先通過(guò)靜態(tài)頁(yè)面的監(jiān)聽(tīng),判斷執(zhí)行什么操作
2.1、點(diǎn)擊添加:對(duì)應(yīng)js調(diào)用addorupdata()方法-->open開(kāi)啟規(guī)定好大小的頁(yè)面,
跳轉(zhuǎn)controller下addorupdata(Integer id,Model model)方法進(jìn)行判斷是
否有id,無(wú)則直接轉(zhuǎn)發(fā)靜態(tài)資源頁(yè)面addorupdata.ftl頁(yè)面,此時(shí)open的小頁(yè)面便
有一個(gè)空的表單頁(yè)面了。
2.2、點(diǎn)擊修改:對(duì)js調(diào)用addorupdata(id)方法-->open開(kāi)啟規(guī)定好大小的頁(yè)面,
帶id轉(zhuǎn)發(fā)至controller層addorupdata(Integer id,Model model)方法判斷
id是否有值,有則存入對(duì)應(yīng)id的User對(duì)象于model中,轉(zhuǎn)發(fā)至addorupdata.ftl頁(yè)
面,此時(shí)open的小頁(yè)面便是一個(gè)有內(nèi)容的表單。
2.3、點(diǎn)擊刪除:js文件會(huì)直接調(diào)用deletesale(data),直接獲取要?jiǎng)h除對(duì)象的id,
多個(gè)這返回拼接一個(gè)ids=1&ids=2&ids=3發(fā)送Ajax請(qǐng)求至controller層調(diào)用delete(Integer[] ids)
方法對(duì)其進(jìn)行處理。
3、其次,判斷什么操作之后,便會(huì)彈出對(duì)應(yīng)窗口addorupdata.ftl,此時(shí)對(duì)應(yīng)js對(duì)其監(jiān)聽(tīng)是否提交
3.1、點(diǎn)擊提交,則會(huì)判斷表單提交數(shù)據(jù)中是否含有id值,有則發(fā)送Ajax請(qǐng)求至controller層
調(diào)用updata(User user)方法對(duì)其進(jìn)行修改。
3.2、點(diǎn)擊提交,id無(wú)值,則發(fā)送Ajax請(qǐng)求至controller層調(diào)用add(User user)方法對(duì)其進(jìn)行添加
4、刪除這里直接寫(xiě)一個(gè)批量刪除即可,無(wú)序打開(kāi)小窗口,直接Ajax請(qǐng)求,調(diào)用controller層的delete方法進(jìn)行處理
其余模塊的邏輯,于營(yíng)銷(xiāo)模塊思路一致,不做更多概述~,源碼直接看上傳資源
⭐核心代碼
SaleChanceController.java
@Controller
@RequestMapping("sale_chance")
public class SaleChanceController extends BaseController {
@Autowired
private SaleChanceService saleChanceService;
@Autowired
private UserService userService;
//營(yíng)銷(xiāo)機(jī)會(huì)頁(yè)面跳轉(zhuǎn)
@RequestMapping("index")
public String toSale(){
return "/saleChance/sale_chance";
}
//添加和修改頁(yè)面
@RequestMapping("addOrUpdateDialog")
public String addorUpdata(Integer id, Model model){
//如果id有值
if(id!=null){
//通過(guò)ID獲取對(duì)象
SaleChance saleChance=saleChanceService.selectByPrimaryKey(id);
model.addAttribute("saleChance",saleChance);
}
return "saleChance/add_update";
}
@RequestMapping("list")
@ResponseBody
public Map<String,Object> manyPage(SaleChanceQuery query){
return saleChanceService.manyPage(query);
}
/*添加商機(jī)*/
@RequestMapping("save")
@ResponseBody
public ResultInfo save(HttpServletRequest req, SaleChance saleChance){
//獲取cookie中的id
int id= LoginUserUtil.releaseUserIdFromCookie(req);
//通過(guò)id創(chuàng)建者
String createName=userService.selectByPrimaryKey(id).getTrueName();
//設(shè)置創(chuàng)建者
saleChance.setCreateMan(createName);
//添加
saleChanceService.addSaleChance(saleChance);
return success("添加成功");
}
/*修改營(yíng)銷(xiāo)機(jī)會(huì)*/
@RequestMapping("updata")
@ResponseBody
public ResultInfo updata(SaleChance saleChance){
saleChanceService.updataSale(saleChance);
return success("修改成功");
}
/*批量刪除*/
@RequestMapping("dels")
@ResponseBody
public ResultInfo delete(Integer[] ids){
System.out.println(Arrays.toString(ids));
saleChanceService.deleteall(ids);
return success("刪除成功~");
}
}
SaleChanceService.java
@Service
public class SaleChanceService extends BaseService<SaleChance,Integer> {
@Resource
private SaleChanceMapper saleChanceMapper;
/*//分頁(yè)顯示*/
public Map<String,Object> manyPage(SaleChanceQuery query){
Map<String, Object> map = new HashMap<>();
//設(shè)置分頁(yè)
PageHelper.startPage(query.getPage(), query.getLimit());
//對(duì)數(shù)據(jù)進(jìn)行分頁(yè)
PageInfo<SaleChance> pageInfo = new PageInfo<>(saleChanceMapper.selectByParams(query));
map.put("code",0);
map.put("msg", "success");
map.put("count", pageInfo.getTotal());
map.put("data", pageInfo.getList());
return map;
}
/* //添加商機(jī)*/
@Transactional(propagation = Propagation.REQUIRED)
public void addSaleChance(SaleChance saleChance){
//判斷客戶(hù)名稱(chēng),機(jī)會(huì)來(lái)源,聯(lián)系人,聯(lián)系電話(huà),
checkInfo(saleChance.getCustomerName(),saleChance.getChanceSource(),saleChance.getLinkMan(),saleChance.getLinkPhone());
//state狀態(tài)是否分配 0 未分配 1已經(jīng)分配
if(StringUtils.isBlank(saleChance.getAssignMan())){
saleChance.setDevResult(0);
saleChance.setState(0);
}
if(StringUtils.isNotBlank(saleChance.getAssignMan())){
saleChance.setDevResult(1);
saleChance.setState(1);
saleChance.setAssignTime(new Date());
}
//設(shè)置默認(rèn)值
saleChance.setCreateDate(new Date());
saleChance.setUpdateDate(new Date());
saleChance.setIsValid(1);
//判斷插入是否成功
AssertUtil.isTrue(insertSelective(saleChance)<1,"添加失?。?);
}
/* //修改商機(jī)*/
@Transactional(propagation = Propagation.REQUIRED)
public void updataSale(SaleChance saleChance){
//通過(guò)id判斷是否存在
SaleChance sc=selectByPrimaryKey(saleChance.getId());
AssertUtil.isTrue(sc==null,"更新商機(jī)不存在!");
//基礎(chǔ)判斷
checkInfo(saleChance.getCustomerName(),saleChance.getChanceSource(),saleChance.getLinkMan(),saleChance.getLinkPhone());
//是否分配]
//原營(yíng)銷(xiāo)機(jī)會(huì)未分配,改為已經(jīng)分配
if(StringUtils.isBlank(sc.getAssignMan()) && saleChance.getAssignMan()!=null){
sc.setState(1);
sc.setDevResult(1);
sc.setAssignTime(new Date());
}
//原營(yíng)銷(xiāo)機(jī)會(huì)已經(jīng)分配,改為未分配
if(StringUtils.isNotBlank(sc.getAssignMan()) && StringUtils.isBlank(sc.getAssignMan())){
sc.setState(0);
sc.setDevResult(0);
sc.setAssignTime(null);
sc.setAssignMan("");
}
//插入
AssertUtil.isTrue(updateByPrimaryKeySelective(saleChance)<1,"添加失??!");
}
/*批量刪除*/
@Transactional(propagation = Propagation.REQUIRED)
public void deleteall(Integer[] ids){
//判斷是否為空
AssertUtil.isTrue((ids==null || ids.length==0),"刪除的ID不存在!");
System.out.println(Arrays.toString(ids));
//刪除是否成功
AssertUtil.isTrue(saleChanceMapper.deleteBatch(ids) < 0,"刪除失敗~~~");
}
//校驗(yàn)
private void checkInfo(String customerName, String chanceSource, String linkMan, String linkPhone) {
AssertUtil.isTrue(StringUtils.isBlank(customerName), "用戶(hù)名稱(chēng)不能為空!");
AssertUtil.isTrue(StringUtils.isBlank(chanceSource),"機(jī)會(huì)來(lái)源不能為空!");
AssertUtil.isTrue(StringUtils.isBlank(linkMan),"聯(lián)系人不能為空!");
AssertUtil.isTrue(StringUtils.isBlank(linkPhone),"聯(lián)系電話(huà)不能為空!");
AssertUtil.isTrue(!PhoneUtil.isMobile(linkPhone),"電話(huà)號(hào)碼不合法!");
}
}
總結(jié)
以上兩個(gè)模塊基本就是這個(gè)項(xiàng)目的全部思路,后面的模塊思路與介紹的這兩個(gè)模塊思路一致,源碼已上傳~,1024程序員節(jié)日快樂(lè)??!🎈🎈🎈🎈
到此這篇關(guān)于Java 初識(shí)CRM之項(xiàng)目思路解析的文章就介紹到這了,更多相關(guān)Java CRM項(xiàng)目思路內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)多線(xiàn)程中的靜態(tài)代理模式
靜態(tài)代理屬于設(shè)計(jì)模式中的代理模式。這篇文章主要介紹了Java實(shí)現(xiàn)多線(xiàn)程中的靜態(tài)代理模式,詳細(xì)的介紹了靜態(tài)代理的使用,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
基于Pinpoint對(duì)SpringCloud微服務(wù)項(xiàng)目實(shí)現(xiàn)全鏈路監(jiān)控的問(wèn)題
這篇文章主要介紹了基于Pinpoint對(duì)SpringCloud微服務(wù)項(xiàng)目實(shí)現(xiàn)全鏈路監(jiān)控的問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02
基于hibernate實(shí)現(xiàn)的分頁(yè)技術(shù)實(shí)例分析
這篇文章主要介紹了基于hibernate實(shí)現(xiàn)的分頁(yè)技術(shù),結(jié)合實(shí)例形式分析了Hibernate分頁(yè)技術(shù)的原理,實(shí)現(xiàn)步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-03-03
JDK14新特性之switch表達(dá)式的實(shí)現(xiàn)
這篇文章主要介紹了JDK14新特性之switch表達(dá)式的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
java substring(a)與substring(a,b)的使用說(shuō)明
這篇文章主要介紹了java substring(a)與substring(a,b)的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
java 中多線(xiàn)程生產(chǎn)者消費(fèi)者問(wèn)題詳細(xì)介紹
這篇文章主要介紹了java 中多線(xiàn)程生產(chǎn)者消費(fèi)者問(wèn)題詳細(xì)介紹的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09
Java多線(xiàn)程之ReentrantReadWriteLock源碼解析
這篇文章主要介紹了Java多線(xiàn)程之ReentrantReadWriteLock源碼解析,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-05-05
Java統(tǒng)計(jì)一個(gè)字符串在另外一個(gè)字符串出現(xiàn)次數(shù)的方法
這篇文章主要介紹了Java統(tǒng)計(jì)一個(gè)字符串在另外一個(gè)字符串出現(xiàn)次數(shù)的方法,涉及java字符串遍歷、正則匹配等相關(guān)操作技巧,需要的朋友可以參考下2018-03-03

