共享益——成果展示

团队博客_隐约雷鸣發表於2024-05-08

共享益——成果展示

頁面展示

image
image
image
image
image

前端部分開發程式碼:

<script setup>
import { User, Lock } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { ref } from "vue";
import { userRegisterService, userLoginService } from "@/api/user.js";
//控制註冊與登入表單的顯示, 預設顯示註冊
const isRegister = ref(false);

//用於註冊的資料模型
const registerData = ref({
    username: "",
    password: "",
    rePassword: "",
});
//定義函式,清空資料模型的資料
const clearRegisterData = () => {
    registerData.value = {
        username: "",
        password: "",
        rePassword: "",
    };
};

//自定義確認密碼的校驗函式
const rePasswordValid = (rule, value, callback) => {
    if (value == null || value === "") {
        return callback(new Error("請再次確認密碼"));
    }
    if (registerData.value.password !== value) {
        return callback(new Error("兩次輸入密碼不一致"));
    }
};
//用於註冊的表單校驗模型
const registerDataRules = ref({
    username: [
        { required: true, message: "請輸入使用者名稱", trigger: "blur" },
        { min: 5, max: 16, message: "使用者名稱的長度必須為5~16位", trigger: "blur" },
    ],
    password: [
        { required: true, message: "請輸入密碼", trigger: "blur" },
        { min: 5, max: 16, message: "密碼長度必須為5~16位", trigger: "blur" },
    ],
    rePassword: [{ validator: rePasswordValid, trigger: "blur" }],
});
// 呼叫後臺介面完成註冊
const register = async () => {
    let result = await userRegisterService(registerData.value);
    console.log("result :>> ", result);
    if (result.code === 0) {
        alert(result.msg ? result.msg : "註冊成功");
    } else {
        alert("註冊失敗");
    }
};
import { useRouter } from 'vue-router';
import { useTokenStore } from '@/stores/token.js';
const router = useRouter();
const tokenStore = useTokenStore();
// 登入函式
const login = async () => {
    let result = await userLoginService(registerData.value);
    //儲存token
    tokenStore.setToken(result.data)

    ElMessage.success('登入成功!')
    router.push('/')
};
</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 登錄檔單 -->
            <!-- 登錄檔單 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData"
                :rules="registerDataRules">
                <el-form-item>
                    <h1>註冊</h1>
                </el-form-item>
                <el-form-item prop="username">
                    <el-input :prefix-icon="User" placeholder="請輸入使用者名稱" v-model="registerData.username"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input :prefix-icon="Lock" type="password" placeholder="請輸入密碼"
                        v-model="registerData.password"></el-input>
                </el-form-item>
                <el-form-item prop="rePassword">
                    <el-input :prefix-icon="Lock" type="password" placeholder="請輸入再次密碼"
                        v-model="registerData.rePassword"></el-input>
                </el-form-item>
                <!-- 註冊按鈕 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register">
                        註冊
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="
                        isRegister = false;
                    clearRegisterData();
                    ">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登入表單 -->
            <el-form ref="form" size="large" autocomplete="off" v-else :model="registerData" :rules="registerDataRules">
                <el-form-item>
                    <h1>登入</h1>
                </el-form-item>
                <el-form-item prop="username">
                    <el-input :prefix-icon="User" placeholder="請輸入使用者名稱" v-model="registerData.username"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="請輸入密碼"
                        v-model="registerData.password"></el-input>
                </el-form-item>
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>記住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘記密碼?</el-link>
                    </div>
                </el-form-item>
                <!-- 登入按鈕 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="login">登入</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="
                        isRegister = true;
                    clearRegisterData();
                    ">
                        註冊 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 樣式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url("@/assets/logo2.png") no-repeat 60% center / 240px auto,
            url("@/assets/login_bg.jpg") no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

後端部分開發程式碼
1.郵箱驗證

package com.example.service.Impl;

import com.example.mapper.UserMapper;
import com.example.pojo.Result;
import com.example.service.IMailService;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class IMailServiceImpl implements IMailService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String mailUserName;

    @Override
    public Result getCode(String username, String email) {
        // 非空校驗
        if (null == username || "".equals(username)) return Result.error("賬號不能為空!");
        if (null == email || "".equals(email)) return Result.error("郵箱不能為空!");

//        System.out.println(staffNumber);
//        System.out.println(mailAddress);
        // 賬號存在校驗
        String email_user = userMapper.getEmailByUsername(username);
//        System.out.println(email);
        if (email_user == null) return Result.error("郵箱不存在!");
        if (!email_user.equals(email)) return Result.error("郵箱不匹配!");


        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String verifyCode = operations.get("verify");
        // 使用當前時間作為種子值
        long seed = System.currentTimeMillis();
        Random random = new Random(seed);
//        if (verifyCode == null) {
        verifyCode = String.valueOf(random.nextInt(899999) + 100000);//生成簡訊驗證碼
//        }
        // 驗證碼存入redis並設定過期時間
        operations.set("verify", verifyCode, 5, TimeUnit.MINUTES);

        // 編寫郵箱內容
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<html><head><title></title></head><body>");
        stringBuilder.append("您好<br/>");
        stringBuilder.append("您的驗證碼是:").append(verifyCode).append("<br/>");
        stringBuilder.append("您可以複製此驗證碼並返回至共享益找回密碼頁面,以驗證您的郵箱。<br/>");
        stringBuilder.append("此驗證碼只能使用一次,在");
//        stringBuilder.append(overtime.toString());
        stringBuilder.append("5分鐘內有效。驗證成功則自動失效。<br/>");
        stringBuilder.append("如果您沒有進行上述操作,請忽略此郵件。");
        MimeMessage mimeMessage = mailSender.createMimeMessage();

        // 發件配置併傳送郵件
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            //這裡只是設定username 並沒有設定host和password,因為host和password在springboot啟動建立JavaMailSender例項的時候已經讀取了
            mimeMessageHelper.setFrom(mailUserName);
            // 使用者的郵箱地址
            mimeMessageHelper.setTo(email);
            // 郵件的標題
            mimeMessage.setSubject("郵箱驗證-共享益");
            // 上面所拼接的郵件內容
            mimeMessageHelper.setText(stringBuilder.toString(), true);
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return Result.success("獲取驗證碼成功,請檢視移步您的郵箱" + email + "檢視驗證碼!");
    }
}

2。訊息處理

package com.example.mapper;

import com.example.pojo.Message;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface MessageMapper {

    //傳送訊息,將傳送的訊息新增到資料庫
    @Insert("INSERT INTO message (id, send_id, receive_id, message, time) VALUES (#{id}, #{sendId}, #{receiveId}, #{message}, now())")
    void sendMessage(Message message);

    //根據自己的id查詢所有給自己傳送過訊息的使用者id
    @Select("SELECT DISTINCT send_id FROM message WHERE receive_id = #{id}")
    List<Integer> findAllSendId(Integer id);

    //根據自己的id查詢所有自己接受到訊息的使用者id
    @Select("SELECT DISTINCT receive_id FROM message WHERE send_id = #{id}")
    List<Integer> findAllReceiveId(Integer id);


    //根據自己的id查詢所有與自己有過會話的使用者id 並根據時間排序
    @Select("""
              SELECT id
              FROM(
              SELECT DISTINCT id ,MAX(time) as time
              FROM (
              SELECT DISTINCT receive_id AS id, MAX(time) as time
              FROM message
              WHERE send_id = #{id}
              GROUP BY receive_id
              UNION
              SELECT DISTINCT send_id AS id, MAX(time) as time
              FROM message
              WHERE receive_id = #{id}
              GROUP BY send_id
            ) merged
            GROUP BY id
            ORDER BY time DESC
            ) merge
            ORDER BY time DESC
            """)
    List<Integer> findAllUserId(Integer id);

    //根據自己的id和另一個人的id查詢所有的訊息 並根據時間先後排序
    @Select("SELECT * FROM message WHERE (send_id = #{myId} AND receive_id = #{otherId}) OR (send_id = #{otherId} AND receive_id = #{myId}) ORDER BY time ASC")
    List<Message> findAllMessage(Integer myId, Integer otherId);

    //刪除與某個人的全部訊息
    @Delete("DELETE FROM message WHERE (send_id = #{myId} AND receive_id = #{otherId}) OR (send_id = #{otherId} AND receive_id = #{myId})")
    void deleteAllMessage(Integer myId, Integer otherId);
}

相關文章