1. 程式人生 > 資料庫 >胖葵酒店管理系統(android客戶端+javaweb服務端+騰訊雲伺服器+騰訊雲資料庫)

胖葵酒店管理系統(android客戶端+javaweb服務端+騰訊雲伺服器+騰訊雲資料庫)

胖葵酒店管理系統app

完整專案已上傳github,連結在文章下面

先看效果圖:

登入:

在這裡插入圖片描述

主頁面(點選右上角圖示進入個人中心頁面):

在這裡插入圖片描述

經理模組(客房管理模組和員工管理模組與經理管理模組類似,員工管理模組還包括增加和刪除員工功能):

在這裡插入圖片描述

修改經理資訊:

在這裡插入圖片描述

新增員工:

在這裡插入圖片描述

刪除員工:

在這裡插入圖片描述

財務查詢模組:

在這裡插入圖片描述

個人中心頁面:

在這裡插入圖片描述

修改密碼:

在這裡插入圖片描述

忘記密碼:

在這裡插入圖片描述

開發工具

客戶端:Android Studio 4.1.0

服務端:IDEA 2020.1

網路通訊框架:Android Volley

簡訊驗證平臺:MobTech SMSSDK

tomcat 9.0

jdk 13.0

資料庫:騰訊雲資料庫Mysql 5.7

伺服器:騰訊雲伺服器Windows Server 2012 R2

客戶端app

專案框架

在這裡插入圖片描述

說明:
activity(從上到下)

1、基礎activity。定義頂部導航欄,供其他頁面繼承使用

2、修改員工。包括增刪改查功能

3、修改經理。包括修改和檢視經理資訊功能

4、修改密碼。

5、修改客房。包括修改和檢視客房資訊功能

6、忘記密碼。包括對使用者輸入手機號是否與資料庫預留的匹配驗證,以及簡訊驗證功能

7、登入。

8、檢視員工資訊資料表

9、檢視經理資訊資料表

10、檢視財務資訊資料表

11、檢視客房資訊資料表

12、主頁面

13、個人中心頁面。包括修改密碼和退出登入功能

14、歡迎頁面

constants

1、儲存使用者登入資訊,用於自動登入功能

help

1、使用者自動登入功能

utils

1、SharedPreferences工具

views

1、輸入樣式,供其他頁面呼叫

主要功能頁

與服務端建立通訊的頁面包括登入頁面、經理資訊管理模組、客房資訊管理模組、員工資訊管理模組、修改密碼模組。下面以登入頁面為例進行說明,其他頁面可以下載程式碼自己看。

登入模組程式碼如下:

package com.example.hotelmanager.activities;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.blankj.utilcode.util.RegexUtils;
import com.example.hotelmanager.R;
import com.example.hotelmanager.help.UserHelp;
import com.example.hotelmanager.utils.SPUtils;
import com.example.hotelmanager.views.InputView;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class Login extends BaseActivity {

    private InputView mInputId, mInputPassword;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        initView();
    }

    //初始化View
    private void initView() {
        initNavBar(false, "登入", false);

        mInputId = findViewById(R.id.input_phone);
        mInputPassword = findViewById(R.id.input_password);
    }


    //登入點選事件
    public void onCommitClick(View v) {
        String id = mInputId.getInputStr();
        String password = mInputPassword.getInputStr();

        //驗證輸入是否合法
        if (!validateLogin(this, id, password)) {
            return;
        }

        SignInRequest(id, password);

    }

    //驗證使用者輸入合法性
    public static boolean validateLogin(Context context, String phone, String password) {
        if (!RegexUtils.isMobileExact(phone)) {
            Toast.makeText(context, "使用者id無效", Toast.LENGTH_SHORT).show();
        }

        if (TextUtils.isEmpty(password)) {
            Toast.makeText(context, "請輸入密碼", Toast.LENGTH_SHORT).show();
            return false;
        }


        //儲存使用者登入標記
        boolean isSaved = SPUtils.saveUser(context, phone);
        if (!isSaved) {
            Toast.makeText(context, "系統錯誤,請稍後重試", Toast.LENGTH_SHORT).show();
            return false;
        }

        UserHelp.getInstance().setPhone(phone);
        
        return true;
    }

    public void onForgetClick(View view) {
        String id = mInputId.getInputStr();

        //驗證輸入是否合法
        if (!validateForget(this, id)) {
            return;
        }
        UserHelp.getInstance().setPhone(id);
        //startActivity(new Intent(this,ChangePassword.class));
        ForgetRequest(id,"****");
    }

    private boolean validateForget(Login login, String phone) {
        if (!RegexUtils.isMobileExact(phone)) {
            Toast.makeText(this, "手機號無效", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    public void SignInRequest(final String username, final String password) {
        //請求地址
        String url = "http://132.232.81.77:8080/HotelServer/loginServlet";
        String tag = "Login";
        //取得請求佇列
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        //防止重複請求,所以先取消tag標識的請求佇列
        requestQueue.cancelAll(tag);
        //建立StringRequest,定義字串請求的請求方式為POST(省略第一個引數會預設為GET方式)
        final StringRequest request = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject jsonObject = (JSONObject) new JSONObject(response).get("params");
                            String result = jsonObject.getString("Result");
                            if (result.equals("TheUserDoesNotExist")) {
                                Toast.makeText(Login.this, "使用者不存在", Toast.LENGTH_SHORT).show();
                            } else if (result.equals("PasswordError")) {
                                Toast.makeText(Login.this, "密碼錯誤", Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(Login.this, "登入成功", Toast.LENGTH_SHORT).show();
                                Intent intent = new Intent(Login.this, MainActivity.class);
                                intent.putExtra("username", username);
                                startActivity(intent);
                                finish();
                            }
                        } catch (JSONException e) {
                            //做自己的請求異常操作,如Toast提示(“無網路連線”等)
                            Log.e("TAG", e.getMessage(), e);
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void one rrorResponse(VolleyError error) {
                //做自己的響應錯誤操作,如Toast提示(“請稍後重試”等)
                Log.e("TAG", error.getMessage(), error);
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("username", username);
                params.put("password", password);
                return params;
            }
        };

        //設定Tag標籤
        request.setTag(tag);

        //將請求新增到佇列中
        requestQueue.add(request);
    }

    public void ForgetRequest(final String username, final String password){
        //請求地址
        String url = "http://132.232.81.77:8080/HotelServer/loginServlet";
        String tag = "Login";
        //取得請求佇列
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        //防止重複請求,所以先取消tag標識的請求佇列
        requestQueue.cancelAll(tag);
        //建立StringRequest,定義字串請求的請求方式為POST(省略第一個引數會預設為GET方式)
        final StringRequest request = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject jsonObject = (JSONObject) new JSONObject(response).get("params");
                            String result = jsonObject.getString("Result");
                            if (result.equals("TheUserDoesNotExist")) {
                                Toast.makeText(Login.this, "使用者不存在", Toast.LENGTH_SHORT).show();
                            }else {
                                Toast.makeText(Login.this, "使用者驗證通過", Toast.LENGTH_SHORT).show();
                                Intent intent = new Intent(Login.this, ForgetPassword.class);
                                intent.putExtra("username",username);
                                startActivity(intent);
                            }
                        } catch (JSONException e) {
                            //做自己的請求異常操作,如Toast提示(“無網路連線”等)
                            Log.e("TAG", e.getMessage(), e);
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void one rrorResponse(VolleyError error) {
                //做自己的響應錯誤操作,如Toast提示(“請稍後重試”等)
                Log.e("TAG", error.getMessage(), error);
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("username", username);
                params.put("password", password);
                return params;
            }
        };

        //設定Tag標籤
        request.setTag(tag);

        //將請求新增到佇列中
        requestQueue.add(request);
    }

}
登陸部分

傳入兩個引數,分別是使用者輸入的id和密碼,請求與服務端建立連線,以Json格式傳給服務端處理,服務端驗證id與密碼是否匹配,將處理結果返回給客戶端,根據接收到的結果將相應的資訊反饋到螢幕提示使用者

忘記密碼部分

其實這裡只需要傳入一個引數,就是使用者id,但為了偷懶我直接複製了登陸部分的程式碼,不必在意這些細節。

同樣請求與服務端建立連線,服務端驗證使用者輸入的id是否存在於資料庫中,將結果返回給客戶端。

關鍵技術點

Android Volley 通訊框架

Volley可以說把非同步網路通訊和網路圖片的載入都封裝於一身,他讓開發者們更輕鬆地進行HTTP通訊和載入網路上的圖片。Volley除了簡單易用之外,在效能上也進行了大幅度的調整,它的設計目標就是非常適合進行資料量不大且通訊頻繁的網路操作,所以並不適合對大資料量的網路操作,比如下載檔案。

如何使用:

1、建立一個android專案

2、匯入volley包

3、宣告網路許可權

4、傳送請求

參考部落格:

https://blog.csdn.net/Mr_Megamind/article/details/74048891

https://blog.csdn.net/perArther/article/details/50856394?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control

webview網頁顯示

WebView的最簡單的使用方式即是直接顯示網頁內容,有以下兩個步驟:

  1. 在佈局檔案中新增WebView控制元件;
  2. 在程式碼中讓WebView控制元件載入顯示網頁。

參考部落格:https://blog.csdn.net/weixin_40438421/article/details/85700109

簡訊驗證服務

這裡簡訊驗證碼服務採用MobTech平臺的SMSSDK簡訊驗證服務,附上平臺連結:https://new.dashboard.mob.com/#/SMSSDK,按照教程在平臺建立應用,會得到一個app key和app secret,如下:

在這裡插入圖片描述

在android studio完成相應的配置即可使用,附上配置教程:https://www.mob.com/wiki/detailed?wiki=SMSSDK_for_Android_kuaisujicheng&id=23

我的配置如下:

在project的build.gradle裡:

在這裡插入圖片描述

在module的build.gradle里加上:

在這裡插入圖片描述

服務端

專案框架

在這裡插入圖片描述
在這裡插入圖片描述

說明:
bean(封裝資料,是資料庫中表的對映)

1、員工表

2、經理資訊表

3、客房表

4、經理id、密碼錶

dao(實現資料的持久化操作,如增刪改查)

1、員工資訊操作

2、經理資訊操作

3、客房資訊操作

4、經理密碼操作

service(業務邏輯的實現)

上面四個Impl分別實現下面四個interface封裝的功能集合

util(工具)

1、連線資料庫

2、讀取配置檔案

web.servlet(服務聯結器,前後端通訊)

1、新增員工

2、修改員工資訊

3、修改經理資訊

4、修改密碼

5、修改客房資訊

6、刪除員工

7、登入(包括忘記密碼)

config

資料庫配置檔案

四個.jsp檔案

1、檢視員工資料表資訊

2、檢視經理資料表資訊

3、檢視財務資料表資訊

4、檢視客房資料表資訊

Style.css

jsp樣式效果

下面主要說一下連線騰訊雲資料庫和servlet部分

配置檔案如下:

url=jdbc:mysql://cdb-fmhwq8ww.cd.tencentcdb.com:10074/hotel?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
driverClass=com.mysql.jdbc.Driver
user=root
password=b980227l

cdb-fmhwq8ww.cd.tencentcdb.com:10074/hotel 這是雲資料庫的外網地址和介面,hotel是專案資料庫

以登入為例說明

.servlet

package PKhotel.web.servlet;

import PKhotel.bean.User;
import PKhotel.service.Impl.UsersServiceImpl;
import PKhotel.util.DButil;
import net.sf.json.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@WebServlet(name="loginServlet")
public class LoginServlet extends HttpServlet {
    DButil dButil = new DButil();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //設定相應內容型別
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        try(PrintWriter out = response.getWriter()){
            String username = request.getParameter("username").trim();
            String password = request.getParameter("password").trim();
            UsersServiceImpl service = new UsersServiceImpl();
            int verigyResult = service.verifyLogin(new User(username,password),dButil);

            Map<String,String> params = new HashMap<>();
            JSONObject jsonObject = new JSONObject();

            if(verigyResult == -1){
                params.put("Result","TheUserDoesNotExist");
            }else if(verigyResult == 0){
                params.put("Result","PasswordError");
            }else if(verigyResult == 1){
                params.put("Result","CorrectPassword");
            }

            jsonObject.put("params",params);
            out.write(jsonObject.toString());

        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

接收客戶端傳來的id和密碼,呼叫service中的verifyLogin函式處理,將結果返回給客戶端

verifyLogin函式如下:

@Override
public int verifyLogin(User u, DButil dButil) {
    List<User> userList = null;
    String username = u.getUsername();
    String password = u.getPassword();
    try{
        userList = userDao.queAll(dButil);
    }catch (Exception e){
        e.printStackTrace();
    }
    boolean hasUser = false;
    boolean rightPass = false;
    for(User user:userList){
        if(user.getUsername().equals(username)){
            hasUser = true;
            if(user.getPassword().equals(password)){
                rightPass = true;
            }
            break;
        }
    }
    if(!hasUser) return -1;//無該使用者
    else if(!rightPass) return 0;//有該使用者,但是密碼輸入錯誤
    return 1;//有該使用者,且密碼輸入正確
}

遍歷資料庫表,驗證是否有該使用者以及密碼與使用者是否匹配

坑點

web專案無法載入css檔案解決方法:https://blog.csdn.net/YOUYOU0710/article/details/106267793/?utm_medium=distribute.pc_relevant.none-task-blog-title-3&spm=1001.2101.3001.4242

專案部署

IDEA將專案打包成war包:https://blog.csdn.net/weixin_43716048/article/details/108639475?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control

將war包部署在雲伺服器:https://blog.csdn.net/zhangjin2024/article/details/101173520?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

檢視資料表資訊

http://132.232.81.77:8080/HotelServer/lookmanager.jsp
http://132.232.81.77:8080/HotelServer/lookorder.jsp
http://132.232.81.77:8080/HotelServer/lookemployees.jsp
http://132.232.81.77:8080/HotelServer/lookroom.jsp

完整專案連結

github:https://github.com/guyuanjunxi/PKHotelManager

csdn:https://download.csdn.net/download/qq_41117896/13208830