Files
ycc-proxy-webview/src/components/AgentApplicationForm.vue

265 lines
8.5 KiB
Vue
Raw Normal View History

2025-11-27 13:19:45 +08:00
<template>
<van-popup v-model:show="show" destroy-on-close round position="bottom">
<div
class="h-12 flex items-center justify-center font-semibold"
style="background-color: var(--van-theme-primary-light); color: var(--van-theme-primary);"
>
成为代理
</div>
<div class="p-4">
2025-12-16 19:27:20 +08:00
<van-field
label-width="56"
v-model="form.referrer"
label="邀请信息"
name="referrer"
placeholder="请输入邀请码/代理编码/代理手机号"
required
/>
2025-11-27 13:19:45 +08:00
<van-field
label-width="56"
v-model="form.region"
is-link
readonly
label="地区"
2025-12-16 19:27:20 +08:00
placeholder="请选择地区(可选)"
2025-11-27 13:19:45 +08:00
@click="showCascader = true"
/>
<van-popup v-model:show="showCascader" round position="bottom">
<van-cascader
v-model="cascaderValue"
title="请选择所在地区"
:options="options"
@close="showCascader = false"
@finish="onFinish"
/>
</van-popup>
<van-field
label-width="56"
v-model="form.mobile"
label="手机号"
name="mobile"
placeholder="请输入手机号"
:readonly="isSelf"
:disabled="isSelf"
/>
<!-- 获取验证码按钮 -->
<div class="flex items-center justify-between">
<van-field
label-width="56"
v-model="form.code"
label="验证码"
name="code"
placeholder="请输入验证码"
/>
<button
class="px-2 py-1 text-sm font-bold flex-shrink-0 rounded-lg transition duration-300"
:class="
isCountingDown || !isPhoneNumberValid
? 'cursor-not-allowed bg-gray-300 text-gray-500'
: 'text-white hover:opacity-90'
"
:style="isCountingDown || !isPhoneNumberValid
? ''
: 'background-color: var(--van-theme-primary);'"
@click="getSmsCode"
:disabled="isCountingDown || !isPhoneNumberValid"
>
{{
isCountingDown ? `${countdown}s重新获取` : "获取验证码"
}}
</button>
</div>
<!-- 同意条款的复选框 -->
<div class="p-4">
<div class="flex items-start">
<van-checkbox
v-model="isAgreed"
name="agree"
icon-size="16px"
class="flex-shrink-0 mr-2"
>
</van-checkbox>
<div class="text-xs leading-tight" style="color: var(--van-text-color-2);">
我已阅读并同意
<a
class="cursor-pointer hover:underline"
style="color: var(--van-theme-primary);"
@click="toUserAgreement"
>用户协议</a
><a
class="cursor-pointer hover:underline"
style="color: var(--van-theme-primary);"
@click="toServiceAgreement"
>信息技术服务合同</a
><a
class="cursor-pointer hover:underline"
style="color: var(--van-theme-primary);"
@click="toAgentManageAgreement"
>推广方管理制度协议</a
>
<div class="text-xs mt-1" style="color: var(--van-text-color-2);">
点击勾选即代表您同意上述法律文书的相关条款并签署上述法律文书
</div>
<div class="text-xs mt-1" style="color: var(--van-text-color-2);">
手机号未在本平台注册账号则申请后将自动生成账号
</div>
</div>
</div>
</div>
<div class="mt-4">
<van-button type="primary" round block @click="submit"
>提交申请</van-button
>
</div>
<div class="mt-2">
<van-button type="default" round block @click="closePopup"
>取消</van-button
>
</div>
</div>
</van-popup>
</template>
<script setup>
const router = useRouter();
const show = defineModel("show");
import { useCascaderAreaData } from "@vant/area-data";
import { showToast } from "vant"; // 引入 showToast 方法
const emit = defineEmits(); // 确保 emit 可以正确使用
const props = defineProps({
isSelf: {
type: Boolean,
default: false,
},
userName: {
type: String,
default: "",
},
});
2025-12-16 19:27:20 +08:00
const { isSelf, userName } = toRefs(props);
2025-11-27 13:19:45 +08:00
const form = ref({
2025-12-16 19:27:20 +08:00
referrer: "",
2025-11-27 13:19:45 +08:00
region: "",
mobile: "",
2025-12-16 19:27:20 +08:00
code: "", // 验证码字段
2025-11-27 13:19:45 +08:00
});
const showCascader = ref(false);
const cascaderValue = ref("");
const options = useCascaderAreaData();
const loadingSms = ref(false); // 控制验证码按钮的loading状态
const isCountingDown = ref(false);
const isAgreed = ref(false);
const countdown = ref(60);
const onFinish = ({ selectedOptions }) => {
showCascader.value = false;
form.value.region = selectedOptions.map((option) => option.text).join("/");
};
const isPhoneNumberValid = computed(() => {
return /^1[3-9]\d{9}$/.test(form.value.mobile);
});
const getSmsCode = async () => {
if (!form.value.mobile) {
showToast({ message: "请输入手机号" });
return;
}
if (!isPhoneNumberValid.value) {
showToast({ message: "手机号格式不正确" });
return;
}
loadingSms.value = true;
const { data, error } = await useApiFetch("auth/sendSms")
.post({ mobile: form.value.mobile, actionType: "agentApply" })
.json();
loadingSms.value = false;
if (data.value && !error.value) {
if (data.value.code === 200) {
showToast({ message: "获取成功" });
startCountdown(); // 启动倒计时
} else {
showToast(data.value.msg);
}
}
};
let timer = null;
function startCountdown() {
isCountingDown.value = true;
countdown.value = 60;
timer = setInterval(() => {
if (countdown.value > 0) {
countdown.value--;
} else {
clearInterval(timer);
isCountingDown.value = false;
}
}, 1000);
}
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
const submit = () => {
// 校验表单字段
2025-12-16 19:27:20 +08:00
if (!form.value.referrer || !form.value.referrer.trim()) {
showToast({ message: "请输入邀请信息" });
2025-11-27 13:19:45 +08:00
return;
}
2025-12-16 19:27:20 +08:00
2025-11-27 13:19:45 +08:00
if (!form.value.mobile) {
showToast({ message: "请输入手机号" });
return;
}
if (!isPhoneNumberValid.value) {
showToast({ message: "手机号格式不正确" });
return;
}
// 如果不是自己申请,则需要验证码
if (!isSelf.value && !form.value.code) {
showToast({ message: "请输入验证码" });
return;
}
if (!isAgreed.value) {
showToast({ message: "请先阅读并同意用户协议及相关条款" });
return;
}
2025-12-16 19:27:20 +08:00
2025-11-27 13:19:45 +08:00
// 触发父组件提交申请
2025-12-16 19:27:20 +08:00
emit("submit", {
...form.value,
referrer: form.value.referrer.trim()
});
2025-11-27 13:19:45 +08:00
};
const closePopup = () => {
emit("close");
};
const toUserAgreement = () => {
router.push({ name: "userAgreement" });
};
const toServiceAgreement = () => {
router.push({ name: "agentSerivceAgreement" });
};
const toAgentManageAgreement = () => {
router.push({ name: "agentManageAgreement" });
};
// 如果是自己申请,则预填并锁定手机号
onMounted(() => {
if (isSelf.value && userName.value) {
form.value.mobile = userName.value;
}
});
</script>