402 lines
11 KiB
Vue
Raw Normal View History

2025-04-22 10:22:33 +08:00
<template>
<view class="register-container p-30">
<!-- 顶部 Logo -->
<image
2025-06-22 18:36:25 +08:00
class="logo"
src="@/static/system/login/logo.png"
mode="aspectFit"
2025-04-22 10:22:33 +08:00
></image>
<!-- 表单区域 -->
<view class="form-card">
<!-- 头像和标题 -->
<view
2025-06-22 18:36:25 +08:00
class="wi-180 he-240 mx-auto r-md mb-20"
style="border: 1px solid #cccccc"
2025-04-22 10:22:33 +08:00
>
<CustomUpload @select="afterRead" :sourceType="['camera']">
<view class="wh-full flex-col-center">
<svg
2025-06-22 18:36:25 +08:00
t="1729656215869"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="5302"
width="32"
height="32"
2025-04-22 10:22:33 +08:00
>
<path
2025-06-22 18:36:25 +08:00
d="M851.552 890.88 172.448 890.88c-74.592 0-135.296-60.672-135.296-135.296L37.152 370.752c0-74.624 60.672-135.328 135.296-135.328l132.16 0L302.912 195.904c0-34.624 28.192-62.816 62.816-62.816l302.016 0c29.408 0 53.312 23.904 53.312 53.312l0 49.024 130.464 0c74.592 0 135.296 60.672 135.296 135.328l0 384.832C986.816 830.208 926.144 890.88 851.552 890.88zM172.448 283.456c-48.128 0-87.296 39.168-87.296 87.328l0 384.832c0 48.128 39.168 87.296 87.296 87.296l679.104 0c48.128 0 87.296-39.168 87.296-87.296L938.848 370.752c0-48.16-39.168-87.328-87.296-87.328L716.8 283.424c-24.096 0-43.712-19.616-43.712-43.712L673.088 186.4c0-2.944-2.368-5.312-5.312-5.312l-302.016 0c-8.16 0-14.816 6.656-14.816 14.816L350.944 237.12c0 25.536-20.768 46.304-46.304 46.304L172.448 283.424zM512 755.84c-107.04 0-194.08-87.072-194.08-194.08S404.992 367.68 512 367.68s194.08 87.072 194.08 194.08S619.04 755.84 512 755.84zM512 415.68c-80.576 0-146.08 65.536-146.08 146.08S431.456 707.84 512 707.84s146.08-65.536 146.08-146.08S592.576 415.68 512 415.68zM816.8 438.016c-25.568 0-46.336-20.768-46.336-46.336s20.768-46.336 46.336-46.336 46.336 20.768 46.336 46.336S842.368 438.016 816.8 438.016zM816.8 390.016l-1.664 1.664c0 0.896 0.736 1.664 1.664 1.664L816.8 390.016z"
fill="#cdcdcd"
p-id="5303"
2025-04-22 10:22:33 +08:00
></path>
</svg>
</view>
</CustomUpload>
<!-- <text class="verify-title">身份验证</text> -->
</view>
<!-- 输入框 -->
<view class="input-group">
<view class="input-item">
2025-06-22 18:36:25 +08:00
<text class="label">
<text class="required">*</text>
姓名:
</text>
2025-04-22 10:22:33 +08:00
<input
2025-06-22 18:36:25 +08:00
class="input-field"
type="text"
v-model="formData.loginName"
placeholder="请输入姓名"
2025-04-22 10:22:33 +08:00
/>
</view>
<view class="input-item">
2025-06-22 18:36:25 +08:00
<text class="label">
<text class="required">*</text>
手机号码:
</text>
2025-04-22 10:22:33 +08:00
<input
2025-06-22 18:36:25 +08:00
class="input-field"
type="number"
v-model="formData.phone"
placeholder="请输入手机号码"
maxlength="11"
2025-04-22 10:22:33 +08:00
/>
</view>
<view class="input-item verification-code-item">
2025-06-22 18:36:25 +08:00
<text class="label">
<text class="required">*</text>
验证码:
</text>
2025-04-22 10:22:33 +08:00
<input
2025-06-22 18:36:25 +08:00
class="input-field verification-code-input"
type="number"
v-model="formData.code"
placeholder="请输入验证码"
maxlength="6"
2025-04-22 10:22:33 +08:00
/>
<button
2025-06-22 18:36:25 +08:00
class="get-code-btn"
:disabled="isCountingDown"
@click="handleGetCode"
2025-04-22 10:22:33 +08:00
>
{{ countdownText }}
</button>
</view>
</view>
<!-- 验证按钮 -->
<button class="verify-btn" @click="handleVerify">验证</button>
</view>
</view>
</template>
<script lang="ts" setup>
2025-06-22 18:36:25 +08:00
import {ref, reactive, computed} from "vue";
2025-04-22 10:22:33 +08:00
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
2025-06-22 18:36:25 +08:00
import {onUnmounted} from "vue";
import {hideLoading, isTabBar, showLoading} from "@/utils/uniapp";
import {attachmentUpload} from "@/api/system/upload";
import {useDataStore} from "@/store/modules/data";
2025-05-13 15:39:44 +08:00
import {
findJsByPhoneApi,
sendCodeApi,
updateUserApi,
} from "@/api/system/login";
2025-06-22 18:36:25 +08:00
import {useUserStore} from "@/store/modules/user";
const {getGlobal} = useDataStore();
2025-04-22 10:22:33 +08:00
const formData = reactive({
2025-05-13 15:39:44 +08:00
loginName: "",
2025-04-22 10:22:33 +08:00
phone: "",
code: "",
2025-05-13 15:39:44 +08:00
avatarUrl: "",
openId: getGlobal.openId,
2025-05-21 02:44:13 +08:00
appCode: getGlobal.type == 1 ? "ZB" : "JS",
2025-04-22 10:22:33 +08:00
});
const countdown = ref(60);
const isCountingDown = ref(false);
let timer: NodeJS.Timeout | null = null;
const countdownText = computed(() => {
return isCountingDown.value ? `${countdown.value}s后重试` : "获取验证码";
});
2025-05-13 15:39:44 +08:00
const handleGetCode = async () => {
2025-04-22 10:22:33 +08:00
if (isCountingDown.value) {
return;
}
if (!formData.phone) {
2025-06-22 18:36:25 +08:00
uni.showToast({title: "请输入手机号码", icon: "none"});
2025-04-22 10:22:33 +08:00
return;
}
2025-05-13 15:39:44 +08:00
const result = await sendCodeApi({
phone: formData.phone,
});
if (result.resultCode == 1) {
2025-06-22 18:36:25 +08:00
uni.showToast({title: "验证码发送成功", icon: "success"});
2025-05-13 15:39:44 +08:00
} else {
2025-06-22 18:36:25 +08:00
uni.showToast({title: "验证码发送失败", icon: "none"});
2025-05-13 15:39:44 +08:00
}
2025-04-22 10:22:33 +08:00
isCountingDown.value = true;
countdown.value = 60; // 重置倒计时
timer = setInterval(() => {
if (countdown.value > 1) {
countdown.value--;
} else {
if (timer) clearInterval(timer);
timer = null;
isCountingDown.value = false;
}
}, 1000);
};
2025-05-21 02:44:13 +08:00
function toHome(data: any) {
if (data.type == 1) {
uni.reLaunch({
url: "/pages/base/groupTeaching/zhujiao",
2025-05-13 15:39:44 +08:00
});
} else {
2025-05-21 02:44:13 +08:00
uni.switchTab({
url: "/pages/base/message/index",
2025-05-13 15:39:44 +08:00
});
}
}
2025-07-08 22:09:38 +08:00
const {afterLoginAction, setJs} = useUserStore();
2025-05-21 02:44:13 +08:00
2025-05-13 15:39:44 +08:00
const handleVerify = async () => {
2025-04-22 10:22:33 +08:00
if (
2025-06-22 18:36:25 +08:00
!formData.loginName ||
!formData.phone ||
!formData.code
// || !formData.avatarUrl
2025-04-22 10:22:33 +08:00
) {
2025-06-22 18:36:25 +08:00
uni.showToast({title: "请填写完整的验证信息", icon: "none"});
2025-04-22 10:22:33 +08:00
return;
}
2025-05-13 15:39:44 +08:00
const result = await updateUserApi({
loginName: formData.loginName,
phone: formData.phone,
code: formData.code,
avatarUrl: formData.avatarUrl,
openId: getGlobal.openId,
2025-05-21 02:44:13 +08:00
appCode: getGlobal.type == 1 ? "ZB" : "JS",
2025-05-13 15:39:44 +08:00
});
if (result.resultCode == 1) {
2025-05-30 15:06:49 +08:00
if (result.result) {
afterLoginAction(result.result);
2025-06-22 18:36:25 +08:00
uni.showToast({title: "验证成功", icon: "success"});
2025-07-08 22:09:38 +08:00
// 立即获取教师信息并存储到jsData中
try {
const findJsByPhoneResult = await findJsByPhoneApi({
phone: formData.phone,
});
if (findJsByPhoneResult.resultCode == 1 && findJsByPhoneResult.result) {
// 将教师信息存储到jsData中
setJs(findJsByPhoneResult.result);
2025-07-09 22:22:34 +08:00
2025-07-08 22:09:38 +08:00
}
} catch (error) {
console.error("获取教师信息失败:", error);
}
2025-05-30 15:06:49 +08:00
if (getGlobal.type == 1) {
toHome(getGlobal);
} else {
const findJsByPhoneResult = await findJsByPhoneApi({
phone: formData.phone,
});
if (findJsByPhoneResult.resultCode == 1) {
if (findJsByPhoneResult.result) {
if (findJsByPhoneResult.result["confirmStatus"] == "A") {
toHome(getGlobal);
} else {
2025-07-08 22:09:38 +08:00
setJs(findJsByPhoneResult.result);
2025-05-30 15:06:49 +08:00
setTimeout(() => {
uni.reLaunch({
url: "/pages/view/hr/teacherProfile/index",
});
}, 1500);
}
2025-05-21 02:44:13 +08:00
} else {
2025-05-30 15:06:49 +08:00
toHome(getGlobal);
2025-05-21 02:44:13 +08:00
}
2025-05-13 15:39:44 +08:00
}
}
2025-05-30 15:06:49 +08:00
} else {
2025-06-22 18:36:25 +08:00
uni.showToast({title: result.message || "验证失败", icon: "none"});
2025-05-13 15:39:44 +08:00
}
} else {
2025-06-22 18:36:25 +08:00
uni.showToast({title: result.message || "验证失败", icon: "none"});
2025-05-13 15:39:44 +08:00
}
2025-04-22 10:22:33 +08:00
};
async function afterRead(event: any) {
2025-06-22 18:36:25 +08:00
showLoading({title: "上传中"});
const {result} = await attachmentUpload(event.tempFilePaths[0]);
2025-04-22 10:22:33 +08:00
hideLoading();
2025-05-13 15:39:44 +08:00
formData.avatarUrl = result[0].filePath;
2025-04-22 10:22:33 +08:00
}
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
</script>
<style scoped lang="scss">
.register-container {
display: flex;
flex-direction: column;
align-items: center;
// height: 100vh; // 使用 min-height 避免内容过长时截断
min-height: 100vh;
background: url("@/static/base/bg.jpg") no-repeat;
background-size: 100% 100%;
padding: 20px;
box-sizing: border-box;
}
.logo {
width: 250px; // 根据实际 logo 尺寸调整
height: 60px; // 根据实际 logo 尺寸调整
margin-top: 40px; // 与顶部的距离
margin-bottom: 30px;
}
.form-card {
background-color: #ffffff;
border-radius: 15px;
padding: 30px 25px;
box-sizing: border-box;
width: 100%;
max-width: 400px; // 限制最大宽度
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center;
}
.avatar-section {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 25px;
}
.avatar {
width: 70px;
height: 70px;
border-radius: 50%;
margin-bottom: 10px;
background-color: #f0f0f0; // 头像占位背景色
}
.verify-title {
font-size: 16px;
color: #333;
font-weight: bold;
}
.input-group {
width: 100%;
margin-bottom: 20px;
}
.input-item {
display: flex;
align-items: center;
margin-bottom: 20px;
border-bottom: 1px solid #eee; // 输入框底部线条
padding-bottom: 10px;
}
.label {
width: 80px; // 固定标签宽度
font-size: 14px;
color: #666;
flex-shrink: 0; // 防止标签被压缩
display: flex; // 使星号和文字对齐
align-items: center;
}
.required {
color: red;
margin-right: 4px;
}
.input-field {
flex-grow: 1;
font-size: 14px;
border: none; // 移除默认边框
outline: none; // 移除选中时的轮廓
padding: 5px 0; // 微调输入框内边距
color: #333;
}
.verification-code-item {
display: flex;
align-items: center;
justify-content: space-between; // 让输入框和按钮分开
}
.verification-code-input {
flex-grow: 1; // 输入框占据剩余空间
margin-right: 10px; // 与按钮的间距
}
.get-code-btn {
background-color: #ffffff;
color: #007aff; // 按钮文字颜色
border: 1px solid #007aff; // 按钮边框
font-size: 12px;
padding: 8px 10px;
border-radius: 20px;
white-space: nowrap; // 防止文字换行
line-height: 1; // 确保文字垂直居中
height: auto; // 自适应高度
margin: 0; // 移除默认外边距
flex-shrink: 0; // 防止按钮被压缩
}
.get-code-btn[disabled] {
background-color: #f8f8f8;
color: #cccccc;
border-color: #cccccc;
}
2025-06-22 18:36:25 +08:00
2025-04-22 10:22:33 +08:00
// 移除按钮默认的边框伪元素
.get-code-btn::after {
border: none;
}
.verify-btn {
width: 100%;
height: 45px;
line-height: 45px;
background: linear-gradient(to right, #ff8c4a, #ff5e62); // 按钮渐变色
color: #ffffff;
font-size: 16px;
border-radius: 25px;
margin-top: 10px;
border: none; // 移除默认边框
box-shadow: 0 2px 5px rgba(255, 100, 100, 0.3); // 添加阴影
}
2025-06-22 18:36:25 +08:00
2025-04-22 10:22:33 +08:00
// 移除按钮默认的边框伪元素
.verify-btn::after {
border: none;
}
// 可以在这里添加 placeholder 的样式
input::placeholder {
color: #cccccc;
font-size: 14px;
}
</style>