传智健康 ----- 移动端开发 (体检预约)
1. 移動端開發
1.1 移動端開發方式
隨著移動互聯網的興起和手機的普及,目前移動端應用變得愈發重要,成為各個商家的必爭之地。例如,我們可以使用手機購物、支付、打車、玩游戲、訂酒店、購票等。以前只能通過PC端完成的事情,現在通過手機就能完成,而且更加方便,而這些都需要移動端開發進行支持,那如何進行移動端開發呢?
移動端開發主要有三種方式:
1. 基于手機API開發(原生APP)
2. 基于手機瀏覽器開發(移動web)
3. 混合開發(混合APP)
1.1.1 基于手機API開發
手機端使用手機API,例如使用Andriod、ios進行開發,服務端只是一個數據提供者,手機端請求服務端獲取數據(json、xml格式)并在頁面展示,這種方式相當于傳統的C/S模式。
1.1.2 基于手機瀏覽器開發
生存在瀏覽器中的應用,基本可以是觸屏版的應用,這種開發方式相當于傳統開發開發中的B/S模式手機上不需要額外安裝軟件,直接基于手機的的瀏覽器進行訪問,這就需要我們編寫的html頁面需要根據不同手機尺寸進行自適應調節,目前比較流行的是html5開發,除了直接通過手機瀏覽器被訪問,還可以將頁面內嵌到一些應用程序中,例如通過微信公眾號訪問html5頁面。
這種方式需要針對不同手機系統分別進行開發,只需要開發一個版本,就可以在不同的手機上訪問。本項目通將我們開發的html5頁面內嵌到微信公眾號進行的。
1.1.3 混合開發
半原生半web混合類APP,需要下載安裝,看上去類似原生APP,訪問的內容是web網頁,其實就是把html5頁面嵌入到一個原生容器容器里面
1.2 微信公眾號開發
1.2.1 賬號分類
要進行微信公眾號,首先訪問微信公眾平臺。官網
本項目選擇訂閱號方式進行公眾號開發。
1.2.2??注冊賬號
要開發微信微信公眾號,首先要注冊成為會員,然后就可以登錄微信公眾平臺進行自定義菜單設置。
注冊頁面
?1.2.3 自定義菜單
在自定義菜單頁面可以根據需求創建一級菜單和二級菜單,其中一級菜單最多可以創建3個,每一個一級菜單下面最多可以創建5個二級菜單,每一個菜單由菜單名稱和菜單內容組成,其中菜單內容有3種形式:發送消息、跳轉網頁、跳轉小程序。
1.2.4 上線要求?
如果是個人用戶身份注冊的訂閱號,則自定義菜單的菜單內容不能進行跳轉網頁,因為個人用戶目前不支持微信認證,而跳轉網頁需要微信認證后才有權限。
如果是企業用戶,首先需要進行微信認證,通過后就可以進行跳轉網頁,跳轉網頁的地址要求必須有域名并且域名需要備案通過。
2. 需求分析和環境搭建
2.1 需求分析
用戶體檢之前需要進行預約,可以通過電話方式進行預約,此時由體檢中心客服人員通過后臺系統錄入預約信息。用戶也可以通過手機端自助預約。本章節開發的功能為用戶通過手機自助預約。
預約流程如下:
1. 訪問移動端首頁
2. 點擊體檢預約進入體檢套餐列表頁面
3. 在體檢套餐列表頁面點擊具體套餐進入套餐詳情頁面
4. 在套餐詳情頁面點擊立即預約進入預約頁面
5. 在預約頁面錄入體檢人相關信息點擊提交預約
2.2 搭建移動端工程
本項目是基于SOA架構進行開發,前面我們已經完成了后臺系統的部分功能開發,在后臺系統中都是通過Dubbo調用服務層發布的服務進行相關操作,本章節我們開發移動端工程也是同樣模式,所以我們要在移動端工程通過Dubbo調用服務層發布的服務,如下圖:
2.2.1 導入maven坐標
?在health_common工程的pom.xml文件中導入阿里短信發送的maven坐標
<dependencies><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>3.3.1</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>1.0.0</version></dependency></dependencies>?
2.2.2 導入通用組件
短信工具類:
隨機生成驗證碼工具類ValidateCodeUtils
package com.itheima.utils;import java.util.Random;/*** 隨機生成驗證碼工具類*/ public class ValidateCodeUtils {/*** 隨機生成驗證碼* @param length 長度為4位或者6位* @return*/public static Integer generateValidateCode(int length){Integer code =null;if(length == 4){code = new Random().nextInt(9999);//生成隨機數,最大為9999if(code < 1000){code = code + 1000;//保證隨機數為4位數字}}else if(length == 6){code = new Random().nextInt(999999);//生成隨機數,最大為999999if(code < 100000){code = code + 100000;//保證隨機數為6位數字}}else{throw new RuntimeException("只能生成4位或6位數字驗證碼");}return code;}/*** 隨機生成指定長度字符串驗證碼* @param length 長度* @return*/public static String generateValidateCode4String(int length){Random rdm = new Random();String hash1 = Integer.toHexString(rdm.nextInt());String capstr = hash1.substring(0, length);return capstr;} }?短信發送工具類SMSUtils
package com.itheima.utils;import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.http.MethodType; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile;/*** 短信發送工具類*/ public class SMSUtils {public static final String VALIDATE_CODE = "SMS_159620392";//發送短信驗證碼public static final String ORDER_NOTICE = "SMS_159771588";//體檢預約成功通知/*** 發送短信* @param phoneNumbers* @param param* @throws ClientException*/public static void sendShortMessage(String templateCode,String phoneNumbers,String param) throws ClientException{// 設置超時時間-可自行調整System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");// 初始化ascClient需要的幾個參數final String product = "Dysmsapi";// 短信API產品名稱(短信產品名固定,無需修改)final String domain = "dysmsapi.aliyuncs.com";// 短信API產品域名(接口地址固定,無需修改)// 替換成你的AKfinal String accessKeyId = "accessKeyId";// 你的accessKeyId,參考本文檔步驟2final String accessKeySecret = "accessKeySecret";// 你的accessKeySecret,參考本文檔步驟2// 初始化ascClient,暫時不支持多region(請勿修改)IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);// 組裝請求對象SendSmsRequest request = new SendSmsRequest();// 使用post提交request.setMethod(MethodType.POST);// 必填:待發送手機號。支持以逗號分隔的形式進行批量調用,批量上限為1000個手機號碼,批量調用相對于單條調用及時性稍有延遲,驗證碼類型的短信推薦使用單條調用的方式request.setPhoneNumbers(phoneNumbers);// 必填:短信簽名-可在短信控制臺中找到request.setSignName("傳智健康");// 必填:短信模板-可在短信控制臺中找到request.setTemplateCode(templateCode);// 可選:模板中的變量替換JSON串,如模板內容為"親愛的${name},您的驗證碼為${code}"時,此處的值為// 友情提示:如果JSON中需要帶換行符,請參照標準的JSON協議對換行符的要求,比如短信內容中包含\r\n的情況在JSON中需要表示成\\r\\n,否則會導致JSON在服務端解析失敗request.setTemplateParam("{\"code\":\""+param+"\"}");// 可選-上行短信擴展碼(擴展碼字段控制在7位或以下,無特殊需求用戶請忽略此字段)// request.setSmsUpExtendCode("90997");// 可選:outId為提供給業務方擴展字段,最終在短信回執消息中將此值帶回給調用者// request.setOutId("yourOutId");// 請求失敗這里會拋ClientException異常SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {// 請求成功System.out.println("請求成功");}} }RedisMessageConstant常量類:
?
package com.itheima.constant;public class RedisMessageConstant {public static final String SENDTYPE_ORDER = "001";//用于緩存體檢預約時發送的驗證碼public static final String SENDTYPE_LOGIN = "002";//用于緩存手機號快速登錄時發送的驗證碼public static final String SENDTYPE_GETPWD = "003";//用于緩存找回密碼時發送的驗證碼 }?2.2.3 health_mobile
創建移動端工程health_mobile,打包方式為war,用于存放Controller,在Controller中通過Dubbo可以遠程訪問服務層相關服務,所以需要依賴health_interface接口工程。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>health_parent</artifactId><groupId>com.itheima</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>health_mobile</artifactId><packaging>war</packaging><name>healthmobile_web Maven Webapp</name><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>com.itheima</groupId><artifactId>health_interface</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><configuration><!-- 指定端口 --><port>80</port><!-- 請求路徑 --><path>/</path></configuration></plugin></plugins></build> </project>靜態資源:
?web.xml:
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app><display-name>Archetype Created Web Application</display-name><!-- 解決post亂碼 --><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定加載的配置文件 ,通過參數contextConfigLocation加載 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping><welcome-file-list><welcome-file>/pages/index.html</welcome-file></welcome-file-list> </web-app>spring-mvc.xml:
<?xml version="1.0" encoding="UTF-8"?> <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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsdhttp://www.springframework.org/schema/contexthttp://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>WriteMapNullValue</value><value>WriteDateUseDateFormat</value></list></property></bean></mvc:message-converters></mvc:annotation-driven><!-- 指定應用名稱 --><dubbo:application name="health_mobile" /><!--指定服務注冊中心地址--><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!--批量掃描--><dubbo:annotation package="com.itheima.controller" /><!--超時全局設置 10分鐘check=false 不檢查服務提供方,開發階段建議設置為falsecheck=true 啟動時檢查服務提供方,如果服務提供方沒有啟動則報錯--><dubbo:consumer timeout="600000" check="false"/><import resource="spring-redis.xml"></import> </beans>spring-redis.xml:
<?xml version="1.0" encoding="UTF-8"?> <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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:redis.properties" /><!--Jedis連接池的相關配置--><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxTotal"><value>${redis.pool.maxActive}</value></property><property name="maxIdle"><value>${redis.pool.maxIdle}</value></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="${redis.host}" /><constructor-arg name="port" value="${redis.port}" type="int" /><constructor-arg name="timeout" value="${redis.timeout}" type="int" /></bean> </beans>redis.properties:
#最大分配的對象數 redis.pool.maxActive=200 #最大能夠保持idel狀態的對象數 redis.pool.maxIdle=50 redis.pool.minIdle=10 redis.pool.maxWaitMillis=20000 #當池內沒有返回對象時,最大等待時間 redis.pool.maxWait=300#格式:redis://:[密碼]@[服務器地址]:[端口]/[db index] #redis.uri = redis://:12345@127.0.0.1:6379/0redis.host = 127.0.0.1 redis.port = 6379 redis.timeout = 30000log4j.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=info, stdout總結
以上是生活随笔為你收集整理的传智健康 ----- 移动端开发 (体检预约)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是“秒杀”?为什么传统项目中也有“秒
- 下一篇: 上海2021高考成绩什么时候可以查询,关