传智健康[一]

1.项目前言

1>. 项目前言

1.项目介绍

  • ①. 甲方:**健康管理机构

  • ②.专业化,流程化,数据化,可视化,集成化

2.原型展示

  • 分两部分:后台管理,微信端(HTML5)

3.技术架构

	前端:HTML5,bootstrpt,vue,elementUI,ajax
	后台:
		1.zk+dubbo(服务注册与调用)
		2.Spring+SpringMVC+Mybatis(主框架)
		3.Spring security安全框架(登录认证)
		4.Mysql+Redis(数据库)
		5.Apache POI(office操作 api)
		6.七牛云文件存储(OSS)
		7.阿里云短信服务(SMS)
		8.微信开发平台(公众号-订阅号)
		9.Git(分布式版本管理),echarts(百度统计API)

传智健康[一]_第1张图片传智健康[一]_第2张图片
4. 软件开发流程 掌握

瀑布与敏捷的区别
	1.瀑布稳定团队或者需求,侧重文档
	2.敏捷需求变动比较频繁,侧重沟通

传智健康[一]_第3张图片
2>. 环境搭建

1. 项目结构

  • 本项目采用maven分模块开发方式,即对整个项目拆分为几个maven工程,每个maven 工程存放特定的一类代码,具体如下:
    传智健康[一]_第4张图片
各模块职责定位:
1.health_parent:父工程,打包方式为pom,统一锁定依赖的版本,同时聚合其他子模块 便于统一
执行maven命令
2.health_common:通用模块,打包方式为jar,存放项目中使用到的一些工具类、实体 类、返回结果
和常量类
3.health_interface:打包方式为jar,存放服务接口
4.health_service_provider:Dubbo服务模块,打包方式为war,存放服务实现类、Dao接 口、
Mapper映射文件等,作为服务提供方,需要部署到tomcat运行
5.health_backend:传智健康管理后台,打包方式为war,作为Dubbo服务消费方,存放 Controller、
HTML页面、js、css、spring配置文件等,需要部署到tomcat运行
6.health_mobile:移动端前台,打包方式为war,作为Dubbo服务消费方,存放 Controller、HTML
页面、js、css、spring配置文件等,需要部署到tomcat运行

2. health_parent

  • 创建一个空目录

  • 创建health_parent,父工程,打包方式为pom,用于统一管理依赖版本 pom.xml

<packaging>pompackaging>

    
    <properties>
        <junit.version>4.12junit.version>
        <spring.version>5.0.5.RELEASEspring.version>
        <pagehelper.version>4.1.4pagehelper.version>
        <servlet-api.version>2.5servlet-api.version>
        <dubbo.version>2.6.0dubbo.version>
        <zookeeper.version>3.4.7zookeeper.version>
        <zkclient.version>0.1zkclient.version>
        <mybatis.version>3.4.5mybatis.version>
        <mybatis.spring.version>1.3.1mybatis.spring.version>
        <mybatis.paginator.version>1.2.15mybatis.paginator.version>
        <mysql.version>5.1.32mysql.version>
        <druid.version>1.0.9druid.version>
        <commons-fileupload.version>1.3.1commons-fileupload.version>
        <spring.security.version>5.0.5.RELEASEspring.security.version>
        <poi.version>3.14poi.version>
        <jedis.version>2.9.0jedis.version>
        <quartz.version>2.2.1quartz.version>
    properties>
    
    <dependencyManagement>
        <dependencies>
            
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-contextartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-beansartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-webartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-webmvcartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-jdbcartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-aspectsartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-jmsartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-context-supportartifactId>
                <version>${spring.version}version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-testartifactId>
                <version>${spring.version}version>
            dependency>
            
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>dubboartifactId>
                <version>${dubbo.version}version>
            dependency>
            <dependency>
                <groupId>org.apache.zookeepergroupId>
                <artifactId>zookeeperartifactId>
                <version>${zookeeper.version}version>
            dependency>
            <dependency>
                <groupId>com.github.sgroschupfgroupId>
                <artifactId>zkclientartifactId>
                <version>${zkclient.version}version>
            dependency>
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.12version>
            dependency>
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>fastjsonartifactId>
                <version>1.2.47version>
            dependency>
            <dependency>
                <groupId>javassistgroupId>
                <artifactId>javassistartifactId>
                <version>3.12.1.GAversion>
            dependency>
            <dependency>
                <groupId>commons-codecgroupId>
                <artifactId>commons-codecartifactId>
                <version>1.10version>
            dependency>
            <dependency>
                <groupId>com.github.pagehelpergroupId>
                <artifactId>pagehelperartifactId>
                <version>${pagehelper.version}version>
            dependency>
            
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatisartifactId>
                <version>${mybatis.version}version>
            dependency>
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatis-springartifactId>
                <version>${mybatis.spring.version}version>
            dependency>
            <dependency>
                <groupId>com.github.miemiedevgroupId>
                <artifactId>mybatis-paginatorartifactId>
                <version>${mybatis.paginator.version}version>
            dependency>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>${mysql.version}version>
            dependency>
            
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>druidartifactId>
                <version>${druid.version}version>
            dependency>
            
            <dependency>
                <groupId>commons-fileuploadgroupId>
                <artifactId>commons-fileuploadartifactId>
                <version>${commons-fileupload.version}version>
            dependency>
            <dependency>
                <groupId>org.quartz-schedulergroupId>
                <artifactId>quartzartifactId>
                <version>${quartz.version}version>
            dependency>
            <dependency>
                <groupId>org.quartz-schedulergroupId>
                <artifactId>quartz-jobsartifactId>
                <version>${quartz.version}version>
            dependency>
            <dependency>
                <groupId>com.sun.jerseygroupId>
                <artifactId>jersey-clientartifactId>
                <version>1.18.1version>
            dependency>
            <dependency>
                <groupId>com.qiniugroupId>
                <artifactId>qiniu-java-sdkartifactId>
                <version>7.2.0version>
            dependency>
            
            <dependency>
                <groupId>org.apache.poigroupId>
                <artifactId>poiartifactId>
                <version>${poi.version}version>
            dependency>
            <dependency>
                <groupId>org.apache.poigroupId>
                <artifactId>poi-ooxmlartifactId>
                <version>${poi.version}version>
            dependency>
            <dependency>
                <groupId>redis.clientsgroupId>
                <artifactId>jedisartifactId>
                <version>${jedis.version}version>
            dependency>
            
            <dependency>
                <groupId>org.springframework.securitygroupId>
                <artifactId>spring-security-webartifactId>
                <version>${spring.security.version}version>
            dependency>
            <dependency>
                <groupId>org.springframework.securitygroupId>
                <artifactId>spring-security-configartifactId>
                <version>${spring.security.version}version>
            dependency>
            <dependency>
                <groupId>org.springframework.securitygroupId>
                <artifactId>spring-security-taglibsartifactId>
                <version>${spring.security.version}version>
            dependency>
            <dependency>
                <groupId>com.github.pengglegroupId>
                <artifactId>kaptchaartifactId>
                <version>2.3.2version>
                <exclusions>
                    <exclusion>
                        <groupId>javax.servletgroupId>
                        <artifactId>javax.servlet-apiartifactId>
                    exclusion>
                exclusions>
            dependency>
            <dependency>
                <groupId>dom4jgroupId>
                <artifactId>dom4jartifactId>
                <version>1.6.1version>
            dependency>
            <dependency>
                <groupId>xml-apisgroupId>
                <artifactId>xml-apisartifactId>
                <version>1.4.01version>
            dependency>
        dependencies>
    dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>servlet-apiartifactId>
            <version>${servlet-api.version}version>
            <scope>providedscope>
        dependency>
    dependencies>
    <build>
        <plugins>
            
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <version>3.2version>
                <configuration>
                    <source>1.8source>
                    <target>1.8target>
                    <encoding>UTF-8encoding>
                configuration>
            plugin>
        plugins>
    build>

2. health_common

  • 创建health_common,子工程,打包方式为jar,存放通用组件,例如工具类、实体类等 pom.xml
    <dependencies>
        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelperartifactId>
        dependency>
        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
        dependency>
        <dependency>
            <groupId>com.github.miemiedevgroupId>
            <artifactId>mybatis-paginatorartifactId>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
        dependency>
        <dependency>
            <groupId>commons-fileuploadgroupId>
            <artifactId>commons-fileuploadartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-beansartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aspectsartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jmsartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-context-supportartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-testartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>dubboartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.zookeepergroupId>
            <artifactId>zookeeperartifactId>
        dependency>
        <dependency>
            <groupId>com.github.sgroschupfgroupId>
            <artifactId>zkclientartifactId>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
        dependency>
        <dependency>
            <groupId>javassistgroupId>
            <artifactId>javassistartifactId>
        dependency>
        <dependency>
            <groupId>commons-codecgroupId>
            <artifactId>commons-codecartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.poigroupId>
            <artifactId>poiartifactId>
        dependency>
        <dependency>
            <groupId>redis.clientsgroupId>
            <artifactId>jedisartifactId>
        dependency>
        <dependency>
            <groupId>com.qiniugroupId>
            <artifactId>qiniu-java-sdkartifactId>
        dependency>
        <dependency>
            <groupId>com.sun.jerseygroupId>
            <artifactId>jersey-clientartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.poigroupId>
            <artifactId>poi-ooxmlartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.securitygroupId>
            <artifactId>spring-security-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.securitygroupId>
            <artifactId>spring-security-configartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.securitygroupId>
            <artifactId>spring-security-taglibsartifactId>
        dependency>
    dependencies>

3. health_interface

  • 创建health_interface,子工程,打包方式为jar,存放服务接口
 <dependencies>
        <dependency>
            <groupId>com.itheima</groupId>
            <artifactId>health_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

4. health_service_provider

  • ①. pom.xml
  <dependencies>
        <dependency>
            <groupId>com.itheimagroupId>
            <artifactId>health_interfaceartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.mavengroupId>
                <artifactId>tomcat7-maven-pluginartifactId>
                <configuration>
                    
                    <port>81port>
                    <uriEncoding>UTF-8uriEncoding>
                    
                    <path>/path>
                configuration>
            plugin>
        plugins>
    build>
  • ②. log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:\\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout
  • ③. spring-dao.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
							http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
							http://www.springframework.org/schema/context
							http://www.springframework.org/schema/context/spring-context.xsd
							http://www.springframework.org/schema/aop
							http://www.springframework.org/schema/aop/spring-aop.xsd
							http://www.springframework.org/schema/tx
							http://www.springframework.org/schema/tx/spring-tx.xsd
							http://www.springframework.org/schema/util
							http://www.springframework.org/schema/util/spring-util.xsd">

    
    <bean id="dataSource"
          class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/health" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    bean>
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:SqlMapConfig.xml" />
    bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        
        <property name="basePackage" value="com.itheima.dao" />
    bean>
beans>
  • ④. spring-service.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/mvc
                            http://www.springframework.org/schema/mvc/spring-mvc.xsd
                            http://code.alibabatech.com/schema/dubbo
                            http://code.alibabatech.com/schema/dubbo/dubbo.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">
    
    <dubbo:application name="health_service_provider"/>
    
    <dubbo:protocol name="dubbo" port="20887"/>
    
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    
    <dubbo:annotation package="com.itheima.service"/>
beans>
  • ⑤. spring-tx.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd">
    
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    bean>
    
    <tx:annotation-driven transaction-manager="transactionManager"
                          proxy-target-class="true"/>
beans>
  • ⑥. SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <plugins>
        <!-- com.github.pagehelper  PageHelper 类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库-->
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>
</configuration>
  • ⑦. web.xml


<web-app>
  <display-name>Archetype Created Web Applicationdisplay-name>

  
  <context-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath*:spring*.xmlparam-value>
  context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  listener>
web-app>

5. health_backend

  • ①. spring-mvc.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/mvc
						http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://code.alibabatech.com/schema/dubbo
						http://code.alibabatech.com/schema/dubbo/dubbo.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context.xsd">
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes" value="application/json"/>
                <property name="features">
                    <list>
                        <value>WriteMapNullValuevalue>
                        <value>WriteDateUseDateFormatvalue>
                    list>
                property>
            bean>
        mvc:message-converters>
    mvc:annotation-driven>
    
    <dubbo:application name="health_backend" />
    
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    
    <dubbo:annotation package="com.itheima.controller" />
    
    <dubbo:consumer timeout="600000" check="false"/>
    
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="104857600" />
        <property name="maxInMemorySize" value="4096" />
        <property name="defaultEncoding" value="UTF-8"/>
    bean>
beans>
  • ②. log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:\\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout
  • ③. web.xml


<web-app>
  <display-name>Archetype Created Web Applicationdisplay-name>
  
  <filter>
    <filter-name>CharacterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    <init-param>
      <param-name>encodingparam-name>
      <param-value>utf-8param-value>
    init-param>
    <init-param>
      <param-name>forceEncodingparam-name>
      <param-value>trueparam-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  <servlet>
    <servlet-name>springmvcservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:springmvc.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>
  <servlet-mapping>
    <servlet-name>springmvcservlet-name>
    <url-pattern>*.dourl-pattern>
  servlet-mapping>
web-app>

(1). 检查项的增删改查

①.列表显示

1>. 检查项列表显示

前台:[触发时机 -> 钩子函数、查询按钮、当页码改变时触发]   
     1.定义分页相关模型数据
     2.页面加载时,在钩子函数中调用findPage()方法
     3.定义findPage()方法。
       3.1 发送ajax请求,param[currentPage、pageSize、queryString]作为参数传递到后台
       3.2 响应后,对每页显示的数据dataList和总记录数total进行赋值

后台:
       1.controller
         将前台输入的参数param封装到一个QueryPageBean中返回一个PageResult[row
         、 total]
       2.service
         2.1 将封装到的QueryPageBean对象三个参数取出
         2.2 利用mybatis进行分业 PageHelper.startPage(currentPage,pageSize)
         2.3 调用dao层对数据库进行查询
         2.4 将page对象中的total和result设置到PageResult中去
       3.dao
         select * from t_checkitem 
            <if test="value!=null and value.length>0">
               where code=#{code} and name = #{value}
            </if>   

前台步骤:
1.定义分页相关模型数据
传智健康[一]_第5张图片
2.页面加载时,在钩子函数中调用findPage()方法
传智健康[一]_第6张图片
传智健康[一]_第7张图片
3.定义findPage()方法
传智健康[一]_第8张图片

后台步骤:
1.controller
在这里插入图片描述
2.service
传智健康[一]_第9张图片
3.dao
传智健康[一]_第10张图片

②. 新增

2>. 新增

  • ①. 新增思路
    前台:
       1.点击新建按钮,触发事件。将模态框设置为可见,要注意重置表单数据
       2.当点击新增按钮触发事件
         2.1 对表格中的数据进行校验
         2.2 如果校验通过
             1>.关闭模态框
             2>.发送ajax请求,将表单中的参数传入后台
             3>.对响应回的结果进行判断;
                    如果正确,给出提示,新增成功
                    如果不正确,给出提示,新增失败
         2.3 如果校验不通过:给出提示
       3. .finally(()=>{ this.findPage(); })  
    后台:
        1.controller:调用service
        2.service 调用dao
        3.dao 对数据库进行查询
  • ②. 前台代码实现

前台代码
1.点击新建按钮,触发事件。将模态框设置为可见,要注意重置表单数据
传智健康[一]_第11张图片
2.当点击新增按钮触发事件
传智健康[一]_第12张图片在这里插入图片描述

  • ③. 后台代码实现

后台步骤:
1.controller:
传智健康[一]_第13张图片
2.service
传智健康[一]_第14张图片
3.Mapper映射文件
传智健康[一]_第15张图片

③. 删除

3>. 删除

  • ①. 删除思路分析
    前台:
        1.点击删除按钮,给出相对应的提示信息。是否进行删除
        2.如果进行删除
           2.1 发送ajax请求,将id作为参数传递进去
           2.2 返回响应结果
               1>.如果删除成功!给出成功提示
               2>.如果删除失败!给出错误提示
        3.如果取消删除:给出提示
        4.调用findPage()方法
   后台:
        1.controller
        2.service[要查询检查项和检查组有关联没]
          2.1 如果有关联则抛出异常,删除失败
          2.2 如果没有关联则删除
        3.dao
          3.1 通过检查项id查询是否和检查项有关联
          3.2 对检查项id进行删除
   
  • ②. 前台代码

前台步骤:
1.需要为删除按钮绑定单击事件,并且将当前行数据作为参数传递给处理函数
传智健康[一]_第16张图片2.弹出确认操作提示
传智健康[一]_第17张图片

  • ③.后台代码

后台步骤:
1.controller
传智健康[一]_第18张图片2.service:
注意:不能直接删除,需要判断当前检查项是否和检查组关联,如果已经和检查组进行了关联则不允许删除
传智健康[一]_第19张图片3.dao
传智健康[一]_第20张图片

④. 修改

4>. 修改

1. 数据回写

  • ①. 通过id查询出检查项对象
[通过id查询CheckItem对象]
   前台:
      1.点击编辑按钮,触发事件。打开模态框
      2.发送ajax请求,将id作为参数传递到后台
      3.如果通过id查找对象成功
      4.如果查找对象失败,则给出提示
   后台:
      1.controller
      2.service
      3.dao
  • ②. 前台步骤

前台步骤:
弹出编辑窗口回显数据
传智健康[一]_第21张图片

  • ③. 后台

后台步骤:
1.controller
传智健康[一]_第22张图片
2.service
在这里插入图片描述
3.dao
传智健康[一]_第23张图片

2. 修改

  • ①. 修改的思路
   前台:
     1.点击修改按钮,对表单进行校验
     2.如果校验成功!
        2.1 关闭模态框
        2.2 发送ajax将表单中的参数传递到后台
        2.3 返回响应结果。给出对应的提示
     3.校验失败,给出提示信息
  • ②.前台步骤
    传智健康[一]_第24张图片
  • ③. 后台步骤

后台步骤:
1.controller
传智健康[一]_第25张图片
2.service
传智健康[一]_第26张图片
3.dao
传智健康[一]_第27张图片

(2). 检查组

  • ①. 为什么点击新建按钮时,将表单数据清除?
    传智健康[一]_第28张图片

  • ②. 当点击lable标签的时候,复选框会被选中
    传智健康[一]_第29张图片

  • ③. 关于mybatis中map作为输入参数parameterType
    传智健康[一]_第30张图片

  • ④. mybatis中分页插件返回值为Page,拿到当前页面的数据使用getResult();
    在这里插入图片描述

  • ⑤. mybatis怎么拿到当前主键 [ selectKey ]?

1.selectKey  通过mybatis框架提供的selectKey来获得自增产生的id值
2.order:insert  selectKey的执行顺序
3.keyProperty:这个属性不能乱写,要对应CheckGroup实体类中的id

    <insert id="add" parameterType="com.itheima.pojo.CheckGroup">
        /*
        通过mybatis框架提供的selectKey来获得自增产生的id值
        order:insert 与 selectKey的执行顺序
        keyProperty:这个属性不能乱写,要对应CheckGroup实体类中的id
        */
       <selectKey resultType="int" order="AFTER" keyProperty="id">
           select LAST_INSERT_ID()
       selectKey>
        insert into t_checkgroup(code,name,helpCode,sex,remark,attention)
        values
        (#{code},#{name},#{helpCode},#{sex},#{remark},#{attention})
    insert>
    
    <insert id="setCheckGroupAndCheckItem" parameterType="map">
        insert into t_checkgroup_checkitem(checkgroup_id,checkitem_id)
        values(#{checkGroupId},#{checkitemId})
    insert>

①.添加

1>. 检查组添加

  • 核心代码如下:
    传智健康[一]_第31张图片
    传智健康[一]_第32张图片

②.检查组修改

2>. 修改

  • ①. 数据回写
前台:
   点击编辑按钮,触发事件。发送三个ajax
   [
   通过检查组id获得当前编辑对象
   获取检查项列表信息
   根据检查组id回写被选中的检查项ids集合 
   ]

后台:
   1.controller
   2.service
     2.1 检查组:通过当前id对数据库中检查组进行修改
     2.2 检查项:将检查组id和被选中的检查项ids作为参数,传递给dao.返回一个List<Integer>
   3.dao

前台代码实现
1.需要为编辑按钮绑定单击事件,并且将当前行数据作为参数传递给处理函数
传智健康[一]_第33张图片2.弹出编辑窗口回显数据
传智健康[一]_第34张图片
后台代码实现
1.controller
传智健康[一]_第35张图片2.service
传智健康[一]_第36张图片3.dao
传智健康[一]_第37张图片

  • ②. 修改操作
前台:
    1.点击修改按钮[对数据进行校验],发送ajax请求,将检查组表单数据和检查项数据
    作为参数传递到后台
    2.在响应中,将模态框进行关闭。看修改是否成功!
      2.1 如果修改成功,给出相对应的提示
      2.2 如果修改失败,给出相对应的提示
    3.在finally中调用findPage()
后台:
    1.controller:将检查组的表单数据和检查项被选中的ids传递给service
    2.service
       检查组: 根据id进行修改
       检查项: 
             根据当前检查组id删除中间表数据
             根据当前检查组的id和被选中的检查项ids 进行中间表添加     

前台:
在编辑窗口中修改完成后,点击确定按钮需要提交请求,所以需要为确定按钮绑定事件并提供处理函数
传智健康[一]_第38张图片
后台:
1.controller:
传智健康[一]_第39张图片2.service
传智健康[一]_第40张图片3.dao
传智健康[一]_第41张图片

(3). 新增套餐

  • ①. 关于文件上传各个参数的说明
    传智健康[一]_第42张图片
  • ②. 什么是UUID?
    UUID 的十六个八位字节被表示为 32个十六进制数字,以连字号分隔的五组来显示,形式为 
8-4-4-4-12,总共有 36个字符(即三十二个英数字母和四个连字号)。例如:
123e4567-e89b-12d3-a456-426655440000
    UUID.randomUUID().toString()+extention;[extention为后缀名]
    (注意:这里的toString()是转成字符串类型)
  • ③. 用elementUI 上传文件中,在人间上传成功后的钩子函数中response相当于response.data
    传智健康[一]_第43张图片

①. 新增

1. 新增

前台: 
   1.点击新建按钮,显示模态框,将套餐数据 | 图片url | 检查组中的数据清空 | 选项卡选中套餐,
发送ajax查询到检查组所有的数据,将查询出来的数据赋值给检查组中表单数据,并显示在页面
   2.点击新建按钮[表单进行验证],将套餐表单数据和检查组中复选框的id作为参数传递到后台.返回
结果[如果为true,则给出成功提示;否则给出失败提示],在返回结果中,要将模态框关闭      
   3.调用findPage方法重新查询页面数据

后台:
   1.controller: 将套餐表单数据和检查组复选框ids作为参数传递给service
   2.service:
      2.1 将套餐数据作为参数传递给dao,进行数据库新增
      注意:这里要拿到当前新增的id,要在insert中使用selectKey标签
      2.2 将套餐新增的id和复选框ids传入到dao,进行中间表数据的添加[重点掌握]
   3.dao Setmeal  中间表的新增   
上传图片并预览
       1.点击 + 号上传图片,action路径会访问controller
       2.将图片传入到七里云中[传入的参数是UUID后缀名]
       UUID:UUID.randomUUID().toString()+extention;
       extention:[
	       String originalFilename = imgFile.getOriginalFilename();//原始文件名
	       String extention=originalFilename.substring
	       (originalFilename.lastIndexOf("."));
       ]
       3.要将传入七牛云的图片传入到redis中
       4.在返回时,要将上传到七牛云图片的名称返回给前台[在新增套餐时,有img这个属性]   
  • ①. 新增前台代码

步骤
效果图:
传智健康[一]_第44张图片传智健康[一]_第45张图片1.新建按钮绑定单击事件,对应的处理函数为handleCreate
传智健康[一]_第46张图片传智健康[一]_第47张图片2.点击新增按钮,触发点击事件
传智健康[一]_第48张图片

  • ②.新增后台步骤

图片预览步骤:
1.前台
传智健康[一]_第49张图片传智健康[一]_第50张图片
2.后台:
传智健康[一]_第51张图片注意:别忘了在spring配置文件中配置文件上传组件
传智健康[一]_第52张图片

新增套餐:
1.controller:
传智健康[一]_第53张图片
2.service
传智健康[一]_第54张图片
3.dao:
传智健康[一]_第55张图片传智健康[一]_第56张图片

②. 定时清理垃圾

传智健康[一]_第57张图片

  • ①. 创建maven工程health_jobs,打包方式为war,导入Quartz等相关坐标
  <packaging>warpackaging>

    <dependencies>
        <dependency>
            <groupId>com.itheimagroupId>
            <artifactId>health_interfaceartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>org.quartz-schedulergroupId>
            <artifactId>quartzartifactId>
        dependency>
        <dependency>
            <groupId>org.quartz-schedulergroupId>
            <artifactId>quartz-jobsartifactId>
        dependency>
    dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.mavengroupId>
                <artifactId>tomcat7-maven-pluginartifactId>
                <configuration>
                    
                    <port>83port>
                    
                    <path>/path>
                configuration>
            plugin>
        plugins>
    build>
  • ②. 配置web.xml


<web-app>
  <display-name>Archetype Created Web Applicationdisplay-name>
  
  <context-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath*:applicationContext*.xmlparam-value>
  context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  listener>
web-app>

  • ③. 配置log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:\\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout
  • ④. 配置applicationContext-redis.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                         http://www.springframework.org/schema/beans/spring-beans.xsd
        				http://www.springframework.org/schema/mvc
                          http://www.springframework.org/schema/mvc/spring-mvc.xsd
        				http://code.alibabatech.com/schema/dubbo
                          http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        				http://www.springframework.org/schema/context
                          http://www.springframework.org/schema/context/spring-context.xsd">

    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal">
            <value>200value>
        property>
        <property name="maxIdle">
            <value>50value>
        property>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
    bean>
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
        <constructor-arg name="host" value="127.0.0.1" />
        <constructor-arg name="port" value="6379" type="int" />
        <constructor-arg name="timeout" value="30000" type="int" />
    bean>
beans>
  • ⑤.配置applicationContext-jobs.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
							http://www.springframework.org/schema/beans/spring-beans.xsd
							http://www.springframework.org/schema/mvc
							http://www.springframework.org/schema/mvc/spring-mvc.xsd
							http://code.alibabatech.com/schema/dubbo
							http://code.alibabatech.com/schema/dubbo/dubbo.xsd
							http://www.springframework.org/schema/context
							http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:annotation-config>context:annotation-config>
    
    <bean id="clearImgJob" class="com.itheima.jobs.ClearImgJob">bean>

    <bean id="jobDetail"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        
        <property name="targetObject" ref="clearImgJob"/>
        
        <property name="targetMethod" value="clearImg"/>
    bean>
    
    <bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        
        <property name="jobDetail" ref="jobDetail"/>
        
        <property name="cronExpression">
            
            <value>0/10 * * * * ?value>
        property>
    bean>
    
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        
        <property name="triggers">
            <list>
                <ref bean="myTrigger"/>
            list>
        property>
    bean>
beans>
  • ⑥. 创建ClearImgJob定时任务类
package com.itheima.jobs;

import com.itheima.constant.RedisConstant;
import com.itheima.utils.QiniuUtils;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.JedisPool;

import java.util.Set;

/*
 * 自定义Job,实现定时清理垃圾图片
 * */
public class ClearImgJob {

    @Autowired
    private JedisPool jedisPool;
    public void clearImg(){
      //根据redis中保存的两个set集合进行差值计算,获取垃圾图片名称集合
        Set<String> set = jedisPool.getResource().sdiff
                (RedisConstant.SETMEAL_PIC_RESOURCES, RedisConstant.SETMEAL_PIC_DB_RESOURCES);
        if(set!=null){
            for (String picName : set) {
                //删除七牛云服务器上的图片
                QiniuUtils.deleteFileFromQiniu(picName);
                //从redis集合中删除集合名称
                jedisPool.getResource().srem(RedisConstant.SETMEAL_PIC_RESOURCES,picName);           
            }
        }
   }
}

(4).预约管理

  • ①. 当前台需要的数据格式和对象不一致时,我们可以用Map来接收。
    传智健康[一]_第58张图片传智健康[一]_第59张图片
  • ②.在Service中传入map作为参数,在dao中parameterType可以使用其子类hashmap 来接收
    传智健康[一]_第60张图片
  • ③. 如果想要传入两个或更多的参数去mapper,我们可以使用map进行传入
    传智健康[一]_第61张图片

①. 批量导入预约设置信息

  • 为什么在service根据日期进行判断是修改还是新增?
如果我们导入两个一样的数据,如果不进行判断,相同的数据会插入两次
	思路:
	1.点击模板下载按钮下载Excel模板文件
	2.将预约设置信息录入到模板文件中
	3.点击上传文件按钮将录入完信息的模板文件上传到服务器
	4.通过POI读取上传文件的数据并保存到数据库
后台:
   1.controller
     1.1 利用POI将文件导入,返回一个List<String[]>
     1.2 创建一个List<OrderSetting>
     1.3 将List<String[]>数据存入List<OrderSetting>集合中
     1.4 将List<OrderSetting>传入service
   2.service
     2.1 对List<OrderSetting> 集合进行判断并循环
     2.2 通过日期查询数据库是否有这条记录
         如果有,则进行修改操作
         如果没有,则进行新增操作
   3.dao

后台代码实现:
1.controller
传智健康[一]_第62张图片
2.service
传智健康[一]_第63张图片
3.dao
传智健康[一]_第64张图片

②.日历展示预约设置

后台:前台需要传入一个data=2019-6
	1.controller:将data数据传入service中,返回一个List<Map>
	2.service:
	   2.1 将传入参数data 分别加上 begin="-01" | end="-31" 将bengin|end 封装到map传入dao
	   2.2 返回一个List<对象>
	   2.3 拿到前台想要的数据类型List<Map>
	3.dao   

步骤:
1.controller
传智健康[一]_第65张图片
2.service
传智健康[一]_第66张图片
3.dao
传智健康[一]_第67张图片

③. 基于日历实现预约设置

  • 为什么要在service进行判断?
    传智健康[一]_第68张图片
前台:需要传入orderDate和num(预约人数)
	1.controller: 将OrderSetting对象作为参数传入service
	2.service:(根据日期查看数据库中是否有这条记录)
	     如果有,进行修改操作
	     如果没有,进行新增操作

后台代码实现:
1.controller
传智健康[一]_第69张图片
2.service
传智健康[一]_第70张图片
3.dao
传智健康[一]_第71张图片

(5).体检预约

  • ①. 怎么获取参数url中参数的id?
//获取指定的URL参数值 http://localhost/pages/setmeal_detail.html?id=3&name=jack
function getUrlParam(paraName) {
    var url = document.location.toString();
    alert(url);//http://localhost/pages/setmeal_detail.html?id=3&name=jack
    var arrObj = url.split("?");//id=3&name=jack
    if (arrObj.length > 1) {
        var arrPara = arrObj[1].split("&");
        var arr;
        for (var i = 0; i < arrPara.length; i++) {
            arr = arrPara[i].split("=");
            if (arr != null && arr[0] == paraName) {
                return arr[1];
            }
        }
        return "";
    }
    else {
        return "";
    }
}

①. 套餐列表页面动态展示

  思路:查询所有的套餐列表

②. 套餐详情页面动态展示

传智健康[一]_第72张图片

  • ①. 套餐Mapper
    <resultMap id="baseResultMap" type="com.itheima.pojo.Setmeal">
        <id column="id" property="id"/> <result column="name" property="name"/>
        <result column="code" property="code"/>
        <result column="helpCode" property="helpCode"/>
        <result column="sex" property="sex"/>
        <result column="age" property="age"/>
        <result column="price" property="price"/>
        <result column="remark" property="remark"/>
        <result column="attention" property="attention"/>
        <result column="img" property="img"/>
    </resultMap>

    <resultMap id="findByIdResultMap"
               type="com.itheima.pojo.Setmeal"
               extends="baseResultMap">
        <!--套餐和检查组之间多对多-->
      <!--  select * from t_setmeal where id=#{id}
      column="id" 这个id就是select*from t...查询出来的id字段名-->
        <collection property="checkGroups"
                    ofType="com.itheima.pojo.CheckGroup"
                    select="com.itheima.dao.CheckGroupDao.findCheckGroupById"
                    column="id">
        </collection>
    </resultMap>
    <!--根据套餐id查询套餐详情、检查组、检查项信息-->
    <select id="findById" resultMap="findByIdResultMap" parameterType="int">
        select * from t_setmeal where id=#{id}
    </select>
    
  • ②.检查组
    <!--关联查询
    根据套餐id查询关联的检查组详情
    -->
    <select id="findCheckGroupById" parameterType="int" resultMap="findByIdResultMap">
    select * from t_checkgroup
    where id in (
    select checkgroup_id from t_setmeal_checkgroup
    where setmeal_id=#{id})
    </select>
        <resultMap type="com.itheima.pojo.CheckGroup" id="baseResultMap">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="code" property="code"/>
        <result column="helpCode" property="helpCode"/>
        <result column="sex" property="sex"/>
        <result column="remark" property="remark"/>
        <result column="attention" property="attention"/>
    </resultMap>
    <resultMap type="com.itheima.pojo.CheckGroup"
               id="findByIdResultMap"
               extends="baseResultMap">
        <!--检查组和检查项关联查询-->
        <collection property="checkItems"
                    ofType="com.itheima.pojo.CheckItem"
                    column="id"
                    select="com.itheima.dao.CheckItemDao.findCheckItemById">
        </collection>
    </resultMap>
  • ③.检查项
    <!--关联查询
    根据检查组id来查询关联的检查项
    -->
    <select id="findCheckItemById" parameterType="int" 
    resultType="com.itheima.pojo.CheckItem">
    select * from t_checkitem where id in (select checkitem_id from 
    t_checkgroup_checkitem where checkgroup_id=#{id})
    </select>

day07 体检预约 重点

知识点小结:
    集合: CollectionUtils.isNotEmpty()
    字符串:StringUtils.equals(validateCodeInRedis,validateCode)

传智健康[一]_第73张图片

①. 发送短信验证

1>. 手机号校验

  • ①. 手机校验前台代码
	1.检查手机号是否合法
	2.倒计时30s倒计时
	3.发送ajax请求,为用发送手机验证码
    //发送验证码
    sendValidateCode(){
        //获取用户输入的手机号this.orderInfo.telephone
        //1.调用checkTelephone()看手机号是否合法
        /**
         * 手机号校验
         1--以1为开头;
         2--第二位可为3,4,5,7,8,中的任意一位;
         3--最后以0-9的9个整数结尾。
         */
        var reg=/^[1][3,4,5,7,8][0-9]{9}$/;
        if (!reg.test(this.orderInfo.telephone)) {
            return false;
        }
        //2.倒计时
        var num1=30;
        var clock1;//定时器变量
        var validateCodeButton1=document.getElementById("validateCodeButton");
        function doLoop1(){
           num1--;
           if(num1>0){
               validateCodeButton1.disabled=true;
                   validateCodeButton1.value=num1+"秒后重新获取";
           }else{
               validateCodeButton1.disabled=false;
               validateCodeButton1.value="重新获取验证码";
               window.clearInterval(clock1);
               num1=30;
           }
        }
        //校验通过,30s倒计时
        clock1= window.setInterval(doLoop1,1000);//定时器方法,每隔指定时间,调用指定方法

        //3.发送ajax请求,为用发送手机验证码
        axios.post("/validateCode/send4Order.do?telephone="+this.orderInfo.telephone)
            .then((res)=>{
                 if(!res.data.flag){
                 //短信验证码发送失败
                     this.$message.error(res.data.message);
                 }
            });
    },
  • ②. 发送短信后台代码
	思想: 
	 1.通过阿里短信服务发送短信
	 2.如果失败,则给出相对应的错误信息
	 3.如果成功,则将短信存入redis
    //用户在线体检预约发送验证码
    @RequestMapping("/send4Order")
    public Result send4Order(String telephone){
        //随机生成4位数字验证码
        Integer validateCode = ValidateCodeUtils.generateValidateCode(4);
        try {
            //给我们用户发送验证码
            SMSUtils.sendShortMessage(SMSUtils.VALIDATE_CODE,telephone,validateCode+"");
        } catch (ClientException e) {
            e.printStackTrace();
            return  new Result(false, MessageConstant.SEND_VALIDATECODE_FAIL);
        }
        //将验证码保存到redis(5分钟) 18774149736001
        jedisPool.getResource().setex(telephone+ RedisMessageConstant.SENDTYPE_ORDER,300,validateCode.toString());
        return new Result(true, MessageConstant.SEND_VALIDATECODE_SUCCESS);
    }

② . 预约

2>. 预约

	controller:
	  1.将用户输入的验证码和redis中保存的验证码进行比对
	  2.如果校验成功,将map参数传入service;根据service返回的结果来进行判断
	  3.如果校验失败,返回错误信息结果给页面
	service:
	  1.检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行 预约
	  2.检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约
	  3.检查用户是否重复预约(同一个用户在同一天预约了同一个套餐),如果是重复预约 则无法完成
	  再次预约
	  4.检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注 册并进行
	  预约
	  5.预约成功,更新当日的已预约人数
    //在线体检预约
    @RequestMapping("/submit")
    /*
     controller:
        1.将redis缓存的验证码和前台输入框中的验证码进行比对
        2.如果比对成功!
           2.1 设置预约类型
           2.2 调用service
           2.3 如果result.isFlag==true 发送成功验证码
        3.如果比对不成功
    * */
    public Result submit(@RequestBody Map map){
           //要知道手机号
           String telephone = (String) map.get("telephone");
          //思路: 先从redis获取保存的验证码
           String validateCodeInRedis=jedisPool.getResource().
                   get(telephone+ RedisMessageConstant.SENDTYPE_ORDER);
          //将用户输入的验证码和redis中保存的验证码进行比对
          String validateCode = (String) map.get("validateCode");
       /*   if(StringUtils.equals(validateCodeInRedis,validateCode)){

          }*/
          if(validateCodeInRedis!=null&&validateCode!=null&&validateCode.equals(validateCodeInRedis)){
              //如果比对成功!调用服务完成预约业务进行处理
              //设置预约的类型,分为: 微信预约 | 电话预约
              map.put("orderType", Order.ORDERTYPE_WEIXIN);
              //通过dubbo来远程调用服务,来实现在线预约业务处理
              Result result=null;
              try {
                  result= orderService.order(map);
              }catch (Exception e){
                  e.getStackTrace();
                  return result;
              }

              if(result.isFlag()){
                  //预约成功!可以为用户发送短信
                  try {
                      SMSUtils.sendShortMessage(SMSUtils.ORDER_NOTICE,telephone,(String)map.get("orderDate"));
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
              return result;
          }else{
              //如果比对失败,返回结果给页面
              return new Result(false, MessageConstant.VALIDATECODE_ERROR);
          }
    }
    //体检预约
    @Override
    public Result order(Map map) throws Exception{
        //1、检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约
            //1.1 获取前台的日期
            String orderDate = (String) map.get("orderDate");
            Date date = DateUtils.parseString2Date(orderDate);

            OrderSetting orderSetting=orderSettingDao.findByOrderDate(date);

            if(orderSetting==null){
                //指定日期没有进行预约设置,则无法完成预约
                return new Result(false, MessageConstant.SELECTED_DATE_CANNOT_ORDER);
            }
        //2、检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约
            //2.1 可预约的人数
            int number = orderSetting.getNumber();
            //2.2 已预约的人数
            int reservations=orderSetting.getReservations();
            if(reservations>=number){
              //预约已满,不能预约
              return new Result(false,MessageConstant.ORDER_FULL);
            }
        //3、检查用户是否重复预约(同一个用户在同一天预约了同一个套餐),如果是重复预约则无法完成再次预约
            String telephone = (String) map.get("telephone");//获取用户页面输入的手机号
            Member member = memberDao.findByTelephone(telephone);

            if(member!=null){
                //判断是否在重复预约
                Integer numberId = member.getId();//会员id
                String setmealId = (String) map.get("setmealId");//套餐id
                //同一个用户同一天预约了同一个套餐
                Order order = new Order(numberId, date, Integer.parseInt(setmealId));

                //根据条件进行查询
                List<Order> list = orderDao.findByCondition(order);
                if(list!=null&&list.size()>0){
                    //说明用户在重复预约,无法完成再次预约
                    return new Result(false,MessageConstant.HAS_ORDERED);
                }

            }else{
                //4、检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注 册并进行预约
                member=new Member();
                member.setName((String) map.get("name"));
                member.setPhoneNumber(telephone);
                member.setIdCard((String) map.get("idCard"));
                member.setSex((String) map.get("sex"));
                member.setRegTime(new Date());
                memberDao.add(member);//自动完成会员注册
            }

         //5、预约成功,更新当日的已预约人数
                Order order = new Order();
                order.setMemberId(member.getId());//设置会员ID
                order.setOrderDate(date);//预约日期
                order.setOrderType((String) map.get("orderType"));//预约类型
                order.setOrderStatus(Order.ORDERSTATUS_NO);//到诊状态
                order.setSetmealId(Integer.parseInt((String) map.get("setmealId")));//套餐ID

                orderDao.add(order);

               //设置已预约人数+1
               orderSetting.setReservations(orderSetting.getReservations()+1);
               orderSettingDao.editReservationsByOrderDate(orderSetting);
        return new Result(true,MessageConstant.ORDER_SUCCESS,order.getId());
    }

传智健康[一]_第74张图片

③. 预约成功

3>. 预约成功
传智健康[一]_第75张图片
传智健康[一]_第76张图片

day08 手机登录 | 权限

①. 通过手机进行验证

1>. 通过手机进行验证

1.需求分析:

  • 手机快速登录功能,就是通过短信验证码的方式进行登录。这种方式相对于用户名密码 登录方式,用户不需要记忆自己的密码,只需要通过输入手机号并获取验证码就可以完 成登录,是目前比较流行的登录方式
    传智健康[一]_第77张图片
    传智健康[一]_第78张图片

2. 发送验证码

思路
	前台:
	  1.验证手机号是否正确
	  2.如果手机号正确,通过定时器来完成倒计时30s
	  3.发送ajax发送验证码[将电话号码作为参数传入后台]
    后台:[controller]
      1.调用阿里接口短信发送[验证码是工具类生成的]
      2.如果发送成功,将验证码保持到redis中
      注意:因为验证码是一次性的,在Redis中保持要用sete(key,time,value)  

步骤:
1.前台代码
传智健康[一]_第79张图片传智健康[一]_第80张图片2.后台代码
[在ValidateCodeController中提供send4Login方法,调用短信服务发送验证码并将验证 码保存到redis]
传智健康[一]_第81张图片

3. 登录

思路
	前台:
	  1.验证手机号是否正确[防止有人直接点击登录]
	  2.如果手机号正确,通过定时器来完成倒计时30s
	  3.发送ajax发送验证码[表单信息作为参数传入后台]
    后台:[controller]
      1.校验用户输入的短信验证码是否正确,如果验证码错误则登录失败
      2.如果验证码正确,则判断当前用户是否为会员,如果不是会员则自动完成会员注册
      3.向客户端写入Cookie,内容为用户手机号
      4.将会员信息保存到Redis,使用手机号作为key,保存时长为30分钟

前台步骤:
1.为登录按钮绑定事件
在这里插入图片描述2.对电话做出判断,发送ajax
传智健康[一]_第82张图片

    //后台代码实现
    @Autowired
    private JedisPool jedisPool;
    @Reference
    private MemberService memberService;
    //手机号快速登录
    @RequestMapping("/login")
    public Result login(@RequestBody Map map, HttpServletResponse response){
        // 获取页面的手机号码
        String telephone= (String) map.get("telephone");
        // 获取redis中的验证码
        String redisCode = jedisPool.getResource().get(telephone + RedisMessageConstant.SENDTYPE_LOGIN);
        // 获取页面的验证码
        String validateCode= (String) map.get("validateCode");
        //1.比对redis中的验证码和输入的验证码是否相同
        if(redisCode!=null&&validateCode!=null&&redisCode.equals(validateCode)){
            //验证码正确
        //2.判断当前用户是否是会员(查询会员表示确定)
        Member member = memberService.findByTelephone(telephone);
            if(member==null){
                //不是会员,自动完成注册(自动将用户信息保持会员表)
                member=new Member();
                member.setRegTime(new Date());
                member.setPhoneNumber(telephone);
                memberService.add(member);
            }

        //3、向客户端写入Cookie,内容为用户手机号
        Cookie cookie=new Cookie("login_member_telephone",telephone);
        cookie.setPath("/");//路径
        cookie.setMaxAge(60*60*24*30);//有效期30天
        response.addCookie(cookie);
        //4、将会员信息保存到Redis,使用手机号作为key,保存时长为30分钟
            String json=JSON.toJSON(member).toString();
            jedisPool.getResource().setex(telephone,60*30,json);
            return new Result(true,MessageConstant.LOGIN_SUCCESS);
        }else{
            //验证码输入错误
            return new Result(false, MessageConstant.VALIDATECODE_ERROR);
        }
    }

你可能感兴趣的:(传智健康[一])