共享益——成果展示
页面展示
前端部分开发代码:
<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);//保存tokentokenStore.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 {@Autowiredprivate UserMapper userMapper;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Autowiredprivate JavaMailSender mailSender;@Value("${spring.mail.username}")private String mailUserName;@Overridepublic 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 idFROM(SELECT DISTINCT id ,MAX(time) as timeFROM (SELECT DISTINCT receive_id AS id, MAX(time) as timeFROM messageWHERE send_id = #{id}GROUP BY receive_idUNIONSELECT DISTINCT send_id AS id, MAX(time) as timeFROM messageWHERE receive_id = #{id}GROUP BY send_id) mergedGROUP BY idORDER BY time DESC) mergeORDER 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);
}