| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <template>
- <view class="auth-content">
- <wd-navbar fixed placeholder :title="title" left-arrow safeAreaInsetTop customClass="navbar" />
- <view class="auth-bg" />
- <view class="auth-body">
- <view class="auth-title">欢迎登录</view>
- <view class="auth-form">
- <!-- 账号 -->
- <AuthInputItem
- label="账号"
- v-model="form.username"
- type="number"
- :maxlength="11"
- placeholder="请输入账号"
- :error="errors.username"
- @clear="clearFieldError('username')"
- @validate="validateField('username')"
- />
- <!-- 密码 -->
- <AuthInputItem
- label="密码"
- v-model="form.password"
- type="number"
- :maxlength="11"
- placeholder="请输入密码"
- passwordToggle
- :error="errors.password"
- @validate="validateField('password')"
- @clear="clearFieldError('password')"
- >
- <template #suffix>
- <view class="forget-password" @click="forgetPassword"> 忘记密码? </view>
- </template>
- </AuthInputItem>
- <!-- 验证码 -->
- <AuthInputItem
- label="验证码"
- v-model="form.code"
- type="number"
- :maxlength="6"
- placeholder="请输入验证码"
- :error="errors.code"
- @clear="clearFieldError('code')"
- @validate="validateField('code')"
- >
- <template #suffix>
- <button class="get-code" :disabled="codeDisabled" @click.stop.prevent="sendCode">
- {{ countdown > 0 ? `${countdown}s 后重试` : '发送验证码' }}
- </button>
- </template>
- </AuthInputItem>
- <!-- 协议 -->
- <view class="agreement">
- <label class="agreement-label">
- <checkbox
- :checked="agreementChecked"
- class="agreement-checkbox"
- @click.stop="toggleAgreement"
- />
- <view class="txt">
- 我已阅读并同意
- <text @click.stop="agreementClick('agreement')"> 《要易云平台用户协议》 </text>、
- <text @click.stop="agreementClick('policy')"> 《隐私权政策》 </text>、
- <text @click.stop="agreementClick('personalInfo')"> 《个人信息使用授权书》 </text>、
- <text @click.stop="handleOpenPrivacyContractClick"> 《用户隐私保护指引》 </text>
- </view>
- </label>
- <view class="error-text" :class="{ visible: agreementError }"> 请阅读并勾选协议 </view>
- </view>
- <!-- 提交 -->
- <view class="submit">
- <button class="submit-btn" type="default" @click="submit">登录</button>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="ts">
- import { onMounted, reactive, ref } from 'vue'
- import projectConfig from '@/config/presets'
- import { debounce } from '@/plugins/debounce'
- import { getAuthTokenApi, getMobileCodeApi } from '@/services/modules/auth'
- import { useCodeCountdown } from '@/composables/useCodeCountdown'
- import { useFormValidator } from '@/composables/useFormValidator'
- import { useUserStore } from '@/stores/modules/user'
- import { resetPasswordRules } from '@/validators/authFormRules'
- import AuthInputItem from '@/components/auth/AuthInputItem.vue'
- const userStore = useUserStore()
- const { title } = projectConfig
- const form = reactive({
- username: '15093284672',
- password: '284672',
- code: '5657',
- })
- const { errors, validate, validateField, clearFieldError } = useFormValidator(
- resetPasswordRules,
- form
- )
- const agreementChecked = ref(false)
- const agreementError = ref(false)
- const toggleAgreement = () => {
- agreementChecked.value = !agreementChecked.value
- if (agreementChecked.value) agreementError.value = false
- }
- const agreementClick = (type: string) => {
- // 打开你自己的协议页面
- }
- const privacyAuthed = ref(false)
- onMounted(() => {
- checkPrivacyAuthorization()
- })
- const checkPrivacyAuthorization = () => {
- wx.getPrivacySetting({
- success(res) {
- if (res.needAuthorization) {
- requirePrivacyAuthorization()
- } else {
- privacyAuthed.value = true
- }
- },
- fail() {
- requirePrivacyAuthorization()
- },
- })
- }
- const requirePrivacyAuthorization = () => {
- wx.requirePrivacyAuthorize({
- success() {
- privacyAuthed.value = true
- },
- fail() {
- uni.showModal({
- title: '提示',
- content: '请同意隐私协议后再使用',
- showCancel: false,
- })
- },
- })
- }
- const handleOpenPrivacyContractClick = () => {
- wx.openPrivacyContract({})
- }
- /* ---------------- 验证码 ---------------- */
- const { countdown, disabled: codeDisabled, start: startCountdown } = useCodeCountdown()
- const toast = (title: string) => uni.showToast({ title, icon: 'none', duration: 800 })
- const sendCodeImpl = async () => {
- if (codeDisabled.value) return
- const [usernameOk, passwordOk] = await Promise.all([
- validateField('username'),
- validateField('password'),
- ])
- if (!usernameOk || !passwordOk) return
- uni.showLoading()
- const res = await getAuthTokenApi({
- username: form.username,
- password: form.password,
- })
- uni.hideLoading()
- if (res.access_token) {
- const codeRes = await getMobileCodeApi(form.username)
- if (codeRes.code === 0) {
- toast('验证码发送成功')
- startCountdown(60)
- } else {
- toast(codeRes.msg || '验证码发送失败')
- }
- }
- }
- const sendCode = debounce(sendCodeImpl)
- /* ---------------- 提交 ---------------- */
- const submit = async () => {
- if (!privacyAuthed.value) {
- requirePrivacyAuthorization()
- return
- }
- const agreementOk = agreementChecked.value
- agreementError.value = !agreementOk
- const formOk = await validate()
- if (!agreementOk || !formOk) return
- uni.showLoading()
- const res = await userStore.login({
- username: form.username,
- code: form.code,
- })
- if (!res.success) {
- uni.showModal({
- title: '登录失败',
- content: res.message ?? '登录失败,请重试',
- showCancel: false,
- confirmText: '我知道了',
- })
- return
- }
- uni.hideLoading()
- uni.reLaunch({
- url: '/pages/index/index',
- })
- }
- /* ---------------- 其他 ---------------- */
- const forgetPassword = () => {
- uni.navigateTo({
- url: '/pages/reset-password/index',
- })
- }
- </script>
- <style lang="scss" scoped>
- @import '../../styles/modules/auth-page.scss';
- </style>
|