大家好,很高兴和大家分享源码。不管是什么样的需求。都希望各位计算机专业的同学们有一个提高。

大家可以通过常用的搜索引擎,以百度为例,搜索 源码乐园 code51 ,然后再次搜索 自己想要的即可。更多的管理系统等,欢迎大家百度搜索源码乐园。

项目运行截图

基于SSM实现的汽车门店管理平台系统

1.项目介绍

1.1项目背景

汽车产业被各国视为支柱型产业,在经济发展的过程中起着举足轻重的作用,全球经济日趋一体化,国际、国内汽车产业竞争越来越激烈,我国汽车产业也面临巨大的机会和挑战,所以采用国际先进的管理思想、现代的管理方式成为汽车产业可持续发展的重要保障之一,汽车产业的企业信息化管理是成为业价值链上的企业提升核心竞争力的不可或缺手段。

在汽车产业价值链上包括汽车制造企业、汽车配件制造企业、汽车销售企业、旧车交易企业、汽车配件销售企业、汽车养护企业、汽车维修企业、汽车租赁企业和驾驶员培训企业等。CareBusiness Suite汽车销售服务管理系统是针对汽车销售企业、汽车养护企业、汽车维修企业和汽车配件企业开发的管理信息系统套件。

CareBusiness Suite构建于CareBusiness平台,作为应用软件的通用基础,CareBusiness平台在多个行业软件中不断被重用,其稳定性得到持续的验证CareBusiness Suite涵盖汽车销售和服务产业的几乎所有业务环节,内置了科学的管理流程,集成了客户关系管理思想,既可以适用于业务单一的汽车服务企业(如只从事汽车销售,或者只从事汽车维修),也适合于包括多种业务种类的汽车服务企业。

SSM项目,后台管理系统,训练的点有SSM、RBAC、Shiro等技术点

1.2系统特点

● CareBusiness Suite的子系统之间有良好的接口,子系统之间可以方便的交换数据,保持了数据的一致性。各个系统既可以独立地运行,也可以与其它子系统联合使用,汽车企业可以根据自身的特征选择相应的子系统及其模块,构建满足自身不同阶段需要的、个性化的企业管理信息系统。

●CareBusiness Suite基于流程而非单据的管理,内置科学的管理流程,实现了汽车企业业务流程化管理的需求。

● CareBusiness Suite集成客户关系管理思想,将企业的交易对象均视为企业的客户(包含法人客户、个人客户、代理商、合作伙伴和供应商等),细腻的个性化客户信息管理,所有的业务信息均与相应客户关联,使得客户历史信息和个性化信息成为客户关怀的重要线索,成为维护客户忠诚度和评估客户终身价值的重要依据。

● CareBusiness Suite支持Windows客户端和IE客户端,栏目布局以矩阵的形式安排,提供栏目跳转、历史线索轨迹和当前线索定位,真正实现360度的数据视图功能,用户使用极为方便。

● CareBusiness Suite将简单查询、复合查询、图表和报表分析集成到模块中,用户获取分析结果极为便捷。查询分析、图表分析和报表分析均针对当前数据集进行,真正做到为每一位用户提供决策支持信息,使得分析功能不再是层次管理者的专利。

● CareBusiness Suite的所有单据和表格可以导出至Excel、Word、HTML、TXT格式文件。支持各种单据(如销售订单、报价单、入库单、出库单和采购计划单等)的生成、预览和打印功能。

● CareBusiness Suite支持多币种和多计量单位的自动换算管理。

1.3软件架构

CareBusiness Suite主要包含了汽车销售管理系统、汽车养护管理系统、汽车维修管理系统和汽车配件管理系统等系统模块,这些系统及其系列模块统一构建于CareBusiness 平台之上,模块之间既相对独立,又可以有机耦合。汽车销售服务企业可以根据自身的业务范围、特点和管理需要,按需选择其中的某些模块,组成自己的管理信息系统。

功能

CareBusiness Suite主要包含了汽车销售管理系统、汽车养护管理系统、汽车维修管理系统和汽车配件管理系统等系统模块,这些系统及其系列模块统一构建于CareBusiness 平台之上,模块之间既相对独立,又可以有机耦合。汽车销售服务企业可以根据自身的业务范围、特点和管理需要,按需选择其中的某些模块,组成自己的管理信息系统。

1.4技术采用

ssm、Freemaker、Shiro、RBAC、RCM、阿里云短信验证、邮箱服务

1.5需求分析

 1.5.1 汽车销售管理:

汽车销售与普通商品销售有着极大的差别,在传统的汽车业管理模式中,纸单据及手工管理是其主流方式。这种方式带来是数据可靠性差,运行效率低下,统计分析难度大,抽取对企业有用信息的可能性极小!显然,这种传统的销售管理模式已经不能适应当今汽车销售企业的市场需求。采用先进管理模式来管理客户关系,采用信息化管理手段培源固本,成为企业提升竞争力的重要途径之一。

汽车销售管理系统包括汽车销售机会管理、门店导购管理、试车管理、报价管理、订单管理和行动管理等销售管理模块,入库管理、出库管理和盘点管理等仓库管理模块,供应商管理、采购询价和采购订单等整车采购管理模块。

对于综合提供整车销售、养护和维修等服务的企业,可以集成选用汽车养护管理等其它系统,共同为企业的信息管理提供支持。

 1.5.2 汽车维修管理:

随着国内汽车行业的发展,这个行业的规模将继续迅速扩大,市场也将更加规范和成熟,竞争更加激烈,汽车维修企业或有维修业务的修理厂、公司约有10万多家,汽车维修已经成为中国汽车产业的重要组成部分。近几年,随着计算机硬件行业的飞速发展,很多经营者正在考虑使用管理软件加强管理。

汽车维修管理系统包括维修业务受理管理、维修派单管理、维修配件领料管理、维修车间管理管理、维修工绩效管理管理、维修结算管理和工具管理管理等。

汽车修理服务主要是处理客户上门服务的业务,汽车施救业务纳入到在汽车养护管理系统中,汽车配件管理业务纳入到汽配管理系统中。三者组合使用,可以形成满足从事多种汽车服务业务企业的管理信息系统。

 1.5.3. 汽车配件管理:

中国汽车配件的经营者约有30多万家,随着社会的飞速发展,当今信息、效率已成为各行各业竞争的武器。在汽配行业中手工的纸和手工具管理己再不能适应市场经济的发展,汽车配件、因其车型之多,零件种类之多等,单靠手工作业管理则难达到科学、准确。电脑在汽配行业的应用,已成为社会发展的必然趋势。

汽配管理系统是针对各汽配店日常的汽车配件的进出、产品的购销、帐款的结算等业务而专门开发的。由于汽配产品繁杂,手工记帐烦琐,不易于统计、分类等现实情况,可能会让您感到忙乱。汽配管理系统不仅能使您从繁琐忙乱的工作中解脱出来,还能为您提供全方位、多层次的系统管理,使您从此一身轻松。汽配管理系统包括配件销售管理、配件采购管理、配件仓库管理、应收应付管理等从事汽车养护和汽车维修的企业一般也包含汽配管理业务,汽配管理系统可以与汽车养护系统、汽车维修系统一道,共同满足您的要求。

1.6典型案例

福建迅速汽车俱乐部(Speed Automobile Association)是福建省首家与国际汽车联会FIA标准接轨的会员权益组织,并率先加入中国旅游车船协会(CTASA)。 SAA倡导现代汽车文化,积极建设专业化、网络化的汽车服务保障体系,SAA的服务宗旨是"迅速救援,驾车无忧"。

客户的忠诚度是企业可持续发展的不竭动力源泉。引进客户关系管理理念,构建CRM系统,是维护客户关系,提升客户忠诚度的重要手段。为此,SAA委托倍特力-亿百合公司建设以CRM为核心的管理信息系统,成为福建省首家导入CRM系统的汽车服务企业,在会员管理、施救服务、汽车美容、代理中间业务和汽车没用用品管理等领域全面实现信息化管理。

SAA管理信息系统的销售模块主要包括客户管理、联系人管理、会员管理、会员发卡管理、机会管理、产品管理、价格管理、合作伙伴管理;服务模块主要包括车辆信息管理、服务协议管理、维修保养服务管理、救援服务管理、服务回访管理、汽车保险管理、汽车年检管理、汽车美容管理和汽车美容用品销售管理;采购和仓库管理模块主要包括美容用品采购管理、美容用品入库管理、美容用品出库管理、盘点管理、安全客户管理、移库管理和调拨管理等;结算管理模块主要包括会员费结算、救援费结算、美容精品结算、年检代理费结算和保险代理费结算等。

2.数据库设计

2.1表结构

活动表

预约表

门店表

投票表

订单表

业务分类表

部门表

员工表

菜单表

留言表

公告表

权限表

角色表

工资表

2.2ER图

3.项目实现

3.1项目配置

<!-- 关联 db.properties 文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置 DataSource bean -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
  init-method="init"
  destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username" value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置 SqlSessionFactory bean -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
  <property name="dataSource" ref="dataSource"/>
  <property name="typeAliasesPackage" value="cn.linstudy.domain"/>
  <property name="mapperLocations" value="classpath:cn/linstudy/mapper/*.xml"/>
  <!-- 注意其他配置 -->
  <property name="plugins">
    <array>
      <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
          <!--使用下面的方式配置参数,一行配置一个,下面配的是合理化分页 -->
          <value>
            pageSizeZero=true
            reasonable=true
          </value>
        </property>
      </bean>
    </array>
  </property>
</bean>

<!-- 配置 SqlSessionFactory bean -->

<!-- 关联主配置文件 目前可以不配置-->
<!-- 配置别名 若不用别名,可以不配置 -->
<!-- 配置数据源-->
<!-- 关联 Mapper XML 可以不配置, 前提编译 Mapper 接口字节码文件与 Mapper XML 文件在一起,文件名也一样 -->

<!-- 配置 Mapper 接口的实现类对象 -->
<!-- 指定 Mapper 接口所在包 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="cn.linstudy.mapper"/>
</bean>

<!-- 配置 IoC DI 注解解析器 , 让 Spring 帮我们创建业务接口的实现类对象, 完成字段注入 -->
<context:component-scan base-package="cn.linstudy.service"/>

<!-- 配置事务管理器 WHAT-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
  id="transactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置增强, WHEN, 并关联上面 WHAT-->
<tx:advice id="interceptor" transaction-manager="transactionManager">
  <tx:attributes>
    <tx:method name="get" read-only="true"/>
    <tx:method name="select" read-only="true"/>
    <tx:method name="list" read-only="true"/>
    <tx:method name="query" read-only="true"/>
    <tx:method name="count" read-only="true"/>
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>
<!-- 配置 AOP -->
<aop:config>
  <aop:pointcut id="txPoint"
    expression="execution(* cn.linstudy.service.impl.*ServiceImpl.*(..))"/>
  <aop:advisor advice-ref="interceptor" pointcut-ref="txPoint"/>
</aop:config>
<!-- WHERE -->
<!-- 关联 WHERE WHEN-->

<!--开启shiro注解扫描-->
<aop:config/>

<!-- Pointcut advisor通知器, 会匹配所有加了shiro权限注解的方法 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
  <property name="securityManager" ref="securityManager"/>
</bean>

3.2安全框架shiro认证

// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
    throws AuthenticationException {
  // 通过token获取用户名(用户登录的时候)
  String username = (String) token.getPrincipal();
  // 判断是否存在在数据库
  Employee employee = employeeService.selectByUsername(username);
  if (employee != null) {
    // 说明此时用户名是对的,返回一个身份对象
    return new SimpleAuthenticationInfo(employee, employee.getPassword(), this.getName());
  }
  return null;
}

// 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  // 创建info对象
  SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
  // 获取当前登录主体对象
  //Subject subject = SecurityUtils.getSubject();
  // 获取主体的身份对象(这里获取的对象与认证方法doGetAuthenticationInfo返回的SimpleAuthenticationInfo对象的第一个参数是同一个对象)
  Subject subject = SecurityUtils.getSubject();
  Employee employee = (Employee) subject.getPrincipal();
  // 判断是否是超级管理员
  if (employee.getAdmin()) {
    info.addRole("admin");
    // 给他所有的权限
    info.addStringPermission(" *:* ");
  } else {
    // 通过员工id拿到所有的角色
    List<Role> roles = employeeService.selectRolesById(employee.getId());
    for (Role role : roles) {
      info.addRole(role.getSn());
    }
    //通过员工id查询出所有的权限
    List<String> permissionByEmployeeId = employeeService
        .getPermissionByEmployeeId(employee.getId());
    info.addStringPermissions(permissionByEmployeeId);
  }
  return info;
}

public class ShiroFreeMarkerConfig extends FreeMarkerConfigurer {

@Override
  public void afterPropertiesSet() throws IOException, TemplateException {
    //继承之前的属性配置,这不能省
    super.afterPropertiesSet();
    Configuration cfg = this.getConfiguration();
    cfg.setSharedVariable("shiro", new ShiroTags());//注册shiro 标签,这里可以换成自己想要其他的标签,但是一般建议是用shiro
  }

3.3全局异常捕捉

// 标记该类为Controller的增强类,用于捕获异常
@ControllerAdvice
public class ExceptionControllerAdvice {

// @ExceptionHandler(异常类型.class)需要处理Controller抛出什么类型的异常.
  @ExceptionHandler(CarBussinessException.class)
  public void handleBussinessException(CarBussinessException carBussinessException,
      HttpServletResponse response, HandlerMethod handlerMethod) throws IOException {
    carBussinessException.printStackTrace();
    // 判断是返回页面还是返回JSON
    ResponseBody methodAnnotation = handlerMethod.getMethodAnnotation(ResponseBody.class);
    if (methodAnnotation == null) {
      // 返回页面
      response.sendRedirect("error");
    } else {
      response.setContentType("application/json;charset=utf-8");
      String responseData = JSON
          .toJSONString(new ResponseResult(false, carBussinessException.getMessage()));
      response.getWriter().write(responseData);
    }
  }

@ExceptionHandler(Exception.class)
  public void BussinessException(Exception exception, HttpServletResponse response,
      HandlerMethod handlerMethod)
      throws IOException {
    exception.printStackTrace();
    ResponseBody methodAnnotation = handlerMethod.getMethodAnnotation(ResponseBody.class);
    if (methodAnnotation == null) {
      response.sendRedirect("/error");
    } else {
      response.setContentType("application/json;charset=utf-8");
      String responseData = JSON.toJSONString(new ResponseResult(false, exception.getMessage()));
      response.getWriter().write(responseData);
    }
  }

@ExceptionHandler(AuthorizationException.class)
  public String BussinessException(AuthorizationException exception, HttpServletResponse response,
      HandlerMethod method) throws IOException {
    exception.printStackTrace(); //方便开发的时候找bug
    //如果原本控制器的方法是返回jsonresult数据,现在出异常也应该返回jsonresult
    //获取当前出现异常的方法,判断是否有ResponseBody注解,有就代表需要返回jsonresult
    if (method.hasMethodAnnotation(ResponseBody.class)) {
      try {
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().print(JSON.toJSONString(new ResponseResult(false, "没有权限操作")));
      } catch (IOException e1) {
        e1.printStackTrace();
      }
      return null;
    }
    //如果原本控制器的方法是返回视图页面,现在也应该返回视图页面
    return "common/nopermission";
  }
}

3.4登陆拦截器

@Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    //请求是静态资源,handler对应的类 class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler
    //请求是动态资源,handler对应的类class org.springframework.web.method.HandlerMethod
    // 如果是动态资源

if (handler instanceof HandlerMethod) {
      Employee employee = (Employee) request.getSession().getAttribute("EMPLOYEE_IN_SESSION");
      if (employee == null) {
        response.sendRedirect("/login.html");
        return false;
      }
      // 查看未读公告的数量
      int unReadNumber = noticeService.unReadNumber(employee.getId());
      // 查询未读公告
      List<Notice> unReadNotice = noticeService.unReadNotice(employee.getId());
      for (Notice notice : unReadNotice) {
        notice.setCalTime(RelativeDateUtils.format(notice.getCreateTime()));
      }
      request.getSession().setAttribute("unReadNumber", unReadNumber);
      request.getSession().setAttribute("unReadNotice", unReadNotice);
    }
    return true;
  }
}

3.5常用工具类

邮箱工具

public static boolean sendEmail(String emailAddress, String code) {
  try {
    //不用更改
    HtmlEmail email = new HtmlEmail();
    //需要修改,126邮箱为smtp.126.com,163邮箱为163.smtp.com,QQ为smtp.qq.com
    email.setHostName("smtp.qq.com");
    email.setCharset("UTF-8");
    // 收件地址
    email.addTo(emailAddress);
    //此处填邮箱地址和用户名,用户名可以任意填写
    email.setFrom("***", "");
    // 此处填写邮箱地址和客户端授权码
    email.setAuthentication("***", "***");

//此处填写邮件名,邮件名可任意填写
    email.setSubject("***");
    //此处填写邮件内容
    email.setMsg("尊敬的用户您好,您本次注册的验证码是:" + code);

email.send();
    return true;
  } catch (Exception e) {
    e.printStackTrace();
    return false;
  }

文件操作

public static String uploadFile(MultipartFile file, String path)
      throws Exception {
   //获取随机值
   String uuid = UUID.randomUUID().toString();
   //获取文件原本的名字
   String fileName = file.getOriginalFilename();
   //获取拓展名,含头不含尾
   String fileType = fileName.substring(fileName.lastIndexOf("."));
   // 拼接上传后的文件名称
   fileName = "/upload/" + uuid + fileType;
   File targetFile = new File(path, fileName);
   //把输入流传进去, 会把内容写到目标文件
   FileUtils.copyInputStreamToFile(file.getInputStream(),targetFile);
   return fileName;
}

/**
 * 删除文件
 @param pic
 */
public static void deleteFile(String pic) {
   File file=new File(pic);
   if(file.exists()) file.delete();
}

验证码生成

/**
 * 使用系统默认字符源生成验证码
 @param verifySize    验证码长度
 * @return
 */
public static String generateVerifyCode(int verifySize){
    return generateVerifyCode(verifySize, VERIFY_CODES);
}
/**
 * 使用指定源生成验证码
 @param verifySize    验证码长度
 * @param sources   验证码字符源
 * @return
 */
public static String generateVerifyCode(int verifySize, String sources){
    if(sources == null || sources.length() == 0){
        sources = VERIFY_CODES;
    }
    int codesLen = sources.length();
    Random rand = new Random(System.currentTimeMillis());
    StringBuilder verifyCode = new StringBuilder(verifySize);
    for(int i = 0; i < verifySize; i++){
        verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));
    }
    return verifyCode.toString();
}

/**
 * 生成随机验证码文件,并返回验证码值
 @param w
 * @param h
 * @param outputFile
 * @param verifySize
 * @return
 * @throws IOException
 */
public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{
    String verifyCode = generateVerifyCode(verifySize);
    outputImage(w, h, outputFile, verifyCode);
    return verifyCode;
}

/**
 * 输出随机验证码图片流,并返回验证码值
 @param w
 * @param h
 * @param os
 * @param verifySize
 * @return
 * @throws IOException
 */
public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{
    String verifyCode = generateVerifyCode(verifySize);
    outputImage(w, h, os, verifyCode);
    return verifyCode;
}

/**
 * 生成指定验证码图像文件
 @param w
 * @param h
 * @param outputFile
 * @param code
 * @throws IOException
 */
public static void outputImage(int w, int h, File outputFile, String code) throws IOException{
    if(outputFile == null){
        return;
    }
    File dir = outputFile.getParentFile();
    if(!dir.exists()){
        dir.mkdirs();
    }
    try{
        outputFile.createNewFile();
        FileOutputStream fos = new FileOutputStream(outputFile);
        outputImage(w, h, fos, code);
        fos.close();
    } catch(IOException e){
        throw e;
    }
}

/**
 * 输出指定验证码图片流
 @param w
 * @param h
 * @param os
 * @param code
 * @throws IOException
 */
public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{
    int verifySize = code.length();
    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Random rand = new Random();
    Graphics2D g2 = image.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    Color[] colors = new Color[5];
    Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
            Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
            Color.PINK, Color.YELLOW };
    float[] fractions = new float[colors.length];
    for(int i = 0; i < colors.length; i++){
        colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
        fractions[i] = rand.nextFloat();
    }
    Arrays.sort(fractions);

g2.setColor(Color.GRAY);// 设置边框色
    g2.fillRect(0, 0, w, h);

Color c = getRandColor(200, 250);
    g2.setColor(c);// 设置背景色
    g2.fillRect(0, 2, w, h-4);

//绘制干扰线
    Random random = new Random();
    g2.setColor(getRandColor(160, 200));// 设置线条的颜色
    for (int i = 0; i < 20; i++) {
        int x = random.nextInt(w - 1);
        int y = random.nextInt(h - 1);
        int xl = random.nextInt(6) + 1;
        int yl = random.nextInt(12) + 1;
        g2.drawLine(x, y, x + xl + 40, y + yl + 20);
    }

3.6业务代码

/**
      * @Description:查询所有门店
      @author XiaoLin
      * @date 2021/3/14
      * @Param: [qo, model]
      * @return java.lang.String
      */
  @RequestMapping("list")
  public String listAll(@ModelAttribute("qo") BusinessQueryObject qo, Model model){

PageInfo<Business> businessPageInfo = businessService.selectForPage(qo);
    model.addAttribute("pageInfo",businessPageInfo);
    return "/business/list";
  }

/**
    * @Description:增加或者删除门店
    @author XiaoLin
    * @date 2021/3/14
    * @Param: [id, model]
    * @return java.lang.String
    */
  @RequestMapping("saveOrUpdate")
  public String saveOrUpdate(Long id,Model model){
    // id不为空说明是编辑,根据id查询门店,放进model对象中
    if (id != null){
      model.addAttribute("business",businessService.selectByPrimaryKey(id));
    }
    // 否则就直接跳转
    return "/business/input";
  }

// 为获取真实路径用
  @Autowired
  ServletContext servletContext;
    /**
        * @Description:修改/增加门店
        @author XiaoLin
        * @date 2021/3/14
        * @Param: [business]
        * @return java.lang.String
        */
    @RequestMapping("updateAndSave")
    public String update(Business business , MultipartFile file) throws Exception {
      if (business.getId() != null){
        // 说明文件不为空,那么就上传营业执照
        if (file != null && file.getSize() >0){
          // 获得webapp的真实路径
          String realPath = servletContext.getRealPath("/");
          // 我们在编辑图片之前,要先看看该公司是否拥有过图片,如果有先删除
          if (StringUtils.hasText(business.getLicenseImg())){
            String deletePath = realPath + business.getLicenseImg();
            FileUploadUtil.deleteFile(deletePath);
          }
          String filePath = FileUploadUtil.uploadFile(file, realPath);
          business.setLicenseImg(filePath);
        }
        businessService.updateByPrimaryKeySelective(business);
        return "redirect:/business/list";
      }else {
        if (file != null && file.getSize()>0){
          String realPath = servletContext.getRealPath("/");
          String filePath = FileUploadUtil.uploadFile(file, realPath);
          business.setLicenseImg(filePath);
        }
        businessService.insertSelective(business);
        return "redirect:/business/list";
      }
    }

4.项目展示

登录

主页

部门管理

员工管理

工资管理

角色管理

字典管理

数据报表

公告管理

留言管理

订单管理

5.总结

通过这次项目的开发,我对数据加密的方式更加了解了,其中加密技术主要可以分为以下几种

不可逆加密算法: 只能加密不能解密 md5 一般对登录密码处理

可逆加密算法: 可以加密,也可以解密 又可以分为是否对称,主要是看秘钥是否是同一个,就是对称,否则就是不对称

  • 对称加密算法:DES,AES等 数据库密码进行加密
    密文为s 加解密算法为AES 秘钥为k,明文为c ;
    加密:s = AES(k,c)
    解密:c = AES(k,s)
  • 非对称加密算法:RSA 网络传输数据加密
    密码是成对出现的,一个私钥就对应一个公钥。如果使用私钥加密,只能使用与之对应公钥来解决。反之如果使用公钥加密,只能使用与之对应私钥解密

技术描述

开发工具: idea/eclipse
数据库: mysql
Jar包仓库: Maven
前段框架:jquery/Jsp
后端框架: spring+springmvc+mybatis

资料说明

汽车产业被各国视为支柱型产业,在经济发展的过程中起着举足轻重的作用,全球经济日趋一体化,国际、国内汽车产业竞争越来越激烈,我国汽车产业也面临巨大的机会和挑战,所以采用国际先进的管理思想、现代的管理方式成为汽车产业可持续发展的重要保障之一,汽车产业的企业信息化管理是成为业价值链上的企业提升核心竞争力的不可或缺手段。

在汽车产业价值链上包括汽车制造企业、汽车配件制造企业、汽车销售企业、旧车交易企业、汽车配件销售企业、汽车养护企业、汽车维修企业、汽车租赁企业和驾驶员培训企业等。CareBusiness Suite汽车销售服务管理系统是针对汽车销售企业、汽车养护企业、汽车维修企业和汽车配件企业开发的管理信息系统套件。

CareBusiness Suite构建于CareBusiness平台,作为应用软件的通用基础,CareBusiness平台在多个行业软件中不断被重用,其稳定性得到持续的验证CareBusiness Suite涵盖汽车销售和服务产业的几乎所有业务环节,内置了科学的管理流程,集成了客户关系管理思想,既可以适用于业务单一的汽车服务企业(如只从事汽车销售,或者只从事汽车维修),也适合于包括多种业务种类的汽车服务企业。

SSM项目,后台管理系统,训练的点有SSM、RBAC、Shiro等技术点

基于SSM+MySQL的实现的汽车门店管理平台系统相关推荐

  1. 基于SSM框架开发生鲜水果蔬菜电商平台系统.rar(含源码及数据库文件)

    基于SSM框架开发,可用于练手,学习开发使用,尤其适合毕业设计,主要功能,商品列表.商品详细页.购物车.登录.注册.商品收藏.订单列表等主要功能.直接用idea或eclipse开发工具,可直接打开项目 ...

  2. 基于SSM实现在线预约驾校练车管理平台

    作者主页:编程指南针 作者简介:Java领域优质创作者.CSDN博客专家 .掘金特邀作者.多年架构师设计经验.腾讯课堂常驻讲师 主要内容:Java项目.毕业设计.简历模板.学习资料.面试题库.技术互助 ...

  3. 基于Java毕业设计安路友汽车租赁源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计安路友汽车租赁源码+系统+mysql+lw文档+部署软件 基于Java毕业设计安路友汽车租赁源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语 ...

  4. 基于ssm+mysql+jsp汽车销售管理系统

    基于ssm+mysql+jsp汽车销售管理系统 一.系统介绍 二.功能展示 1.用户登陆 2.主页 3.营销管理 4.汽车管理 5.活动管理 6.试驾管理 7.商机管理 8.订单管理 9.客户管理 1 ...

  5. 基于SSM车辆维修管理系统-JavaWeb汽车保养管理系统

    基于SSM车辆维修管理系统-JavaWeb汽车保养管理系统 基于ssm框架实现一个车辆维修管理系统(java+springmvc+mybatis+mysql),能够实现用户信息管理.车辆信息管理.故障 ...

  6. 教你手把手基于java实现兼职招聘系统、基于SSM+mysql的Web校园招聘网站

    Java实现的兼职招聘系统.基于SSM+mysql的Web校园招聘网站 后期会继续实现springboot版本 需要学习的可以一起交流 项目环境 SSM JSP.JSTL.jQuery.HTML.CS ...

  7. 基于SSM+Mysql的房屋租赁管理系统

    一.基于SSM+Mysql的房屋租赁管理系统 1.具有角色功能[管理员.租户] 管理员 房源信息管理.租赁合同信息.申请列表.报障模块(处理报障).租金信息(收租管理).我的日程管理.账户管理: 租户 ...

  8. javaweb仓库管理系统的实现,基于ssm+mysql实现的WMS进销存出库入库系统

    javaweb仓库管理系统的实现,基于ssm+mysql实现的WMS进销存出库入库系统 感兴趣的朋友可以家 3060912346 主要技术 SpringBoot\SSM(两个版本都有) HTML.jQ ...

  9. 基于SSM + MySQL的服饰服装购物平台系统的设计与实现源码+论文+包安装配置+讲解视频

    下载:https://download.csdn.net/download/nike8x/83598568 项目介绍: 基于SSM + MySQL的服饰服装购物平台系统的设计与实现源码+论文+包安装配 ...

  10. 基于SSM+MYSQL写的javaWeb房屋租赁管理系统,包括系统前端和后台,页面美观,功能完善,非常高端的SSM源码

    基于SSM+MYSQL写的javaWeb房屋租赁管理系统,包括系统前端和后台,页面美观,功能完善,非常高端的毕业设计 课程设计. ​ 基于SSM+MYSQL写的javaWeb房屋租赁管理系统,包括系统 ...

最新文章

  1. access导出MySQL表格_如何将Access数据库里的表内容导出到Excel
  2. PDO的bindParam与bindValue的区别
  3. 写出最感兴趣的软件测试工作,你还不会写测试用例?!注意这五点,写出模板级的测试用例!...
  4. ABAP Graphics FM Overview
  5. 3-无重复字符的最长子串(中等)
  6. 未来已来,音视频江湖再起波澜
  7. 操作系统:提升电脑开机速度的15个小技巧
  8. ejb能调用另一个ejb吗_异步EJB只是一个Gi头吗?
  9. Java03接口与内部类
  10. Linux 用C/C++创建新文件并写入内容
  11. 2017电大c语言考试时间,2017年电大 《c语言程序设计》a课程考核说明.doc
  12. Nginx基本数据结构之ngx_list_t
  13. mongodb的副本集总结
  14. 官宣|Apache Flink 1.14.0 发布公告
  15. C# 设置和获取一个字节的某一位的值的方法 .
  16. 最经典的PS入门笔记,来自李涛老师的高手之路
  17. 怎么用计算机计算最小二乘法,最小二乘法_在线最小二乘法计算器
  18. oracle全量增量_数据上云,应该选择全量抽取还是增量抽取?
  19. Windows11 C盘清理-系统休眠文件占用15G
  20. [原创] 简单的几个步骤`皮肤变得晶莹剔透

热门文章

  1. mysql与linux版本区别_MySQL各版本的区别
  2. Matlab程序如何打包
  3. java小白必看:如何用java创建一个窗口
  4. java 设置颜色_java 中怎样设置窗口的颜色
  5. 媲美Teamviewer的远程桌面软件推荐 总有一款适合你
  6. 2 EDA技术实用教程【Verilog 语句基本类型】
  7. 微软MSDN原版所有系统合集我告诉你,Windows历史操作系统索引
  8. 【编程学习】每天进步一点点,编程学习之路:一款Mdict词典制作工具,Mdict Editor Tool v2.0.35 -- 多功能个性化词典制作工具
  9. Android 科大讯飞离线语音识别
  10. c语言程序设计pdf下载上海交大,C语言程序设计第1章参考标准答案(上海交大出版社).doc...