演示视频

是否包含论文文档

项目技术

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

项目截图描述

基于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.comQQsmtp.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.项目展示

登录

 

 

 

主页

 

 

 

部门管理

 

 

 

员工管理

 

 

 

工资管理

 

 

 

角色管理

 

 

 

字典管理

 

 

 

数据报表

 

 

 

公告管理

 

 

留言管理

 

 

订单管理

详细描述

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

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

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

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

分享地址

复制地址转发给你的小伙伴:) https://code99.top/979.html

主题授权提示:请在后台主题设置-主题授权-激活主题的正版授权,授权购买:RiTheme官网

注册登录网站->在项目页面点击“立即购买”按钮->支付订单->网页内点击“点我下载”按钮(支付后可见)->完成下载

源码素材属于虚拟商品,具有可复制性,可传播性,一旦授予,不接受任何形式的退款、换货要求。

如果您已经成功付款但是网站没有弹出成功提示,请联系站长提供付款信息为您处理

在项目页面的右上角,标题左方,会有“免费安装”或者“付费安装”字眼提示,如果是免费安装不需要付费即可安装,需要配合站长下载工具包等事项,操作步骤如下,http://code99.top/423.html,如果是付费则需要另外付费,站长提供了安装部署文档,可以自行安装。不想麻烦,则需要购买安装服务。购买地址如下:http://code99.top/453.html