feat(aihr): complete uni-app role workflows
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<view class="page login-page">
|
||||
<view class="login-head">
|
||||
<text class="page-title">银城员工端</text>
|
||||
<text class="page-subtitle">使用手机号登录后,回到当前任务。</text>
|
||||
</view>
|
||||
|
||||
<view class="panel login-card">
|
||||
<text class="panel-title">手机号登录</text>
|
||||
<input
|
||||
v-model="phone"
|
||||
class="input"
|
||||
type="number"
|
||||
maxlength="11"
|
||||
placeholder="请输入手机号"
|
||||
/>
|
||||
<view class="inline-actions">
|
||||
<input
|
||||
v-model="smsCode"
|
||||
class="input code-input"
|
||||
type="number"
|
||||
maxlength="6"
|
||||
placeholder="验证码"
|
||||
/>
|
||||
<button class="secondary-button code-button" :disabled="sending" @click="sendCode">
|
||||
{{ sending ? '发送中' : '发验证码' }}
|
||||
</button>
|
||||
</view>
|
||||
<button class="primary-button" :disabled="loggingIn" @click="login">
|
||||
{{ loggingIn ? '登录中' : '登录' }}
|
||||
</button>
|
||||
<text v-if="message" class="status-message">{{ message }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import type { LoginResult } from '@/types/api';
|
||||
import { apiRequest } from '@/services/api';
|
||||
import { consumeLoginRedirect, getAuth, isLoggedIn, phoneKey, saveAuth, validatePhone } from '@/services/auth';
|
||||
|
||||
const stored = getAuth();
|
||||
const phone = ref(stored.phone || uni.getStorageSync(phoneKey) || '');
|
||||
const smsCode = ref('');
|
||||
const sending = ref(false);
|
||||
const loggingIn = ref(false);
|
||||
const message = ref('');
|
||||
const tabPages = new Set([
|
||||
'/pages/user/today/index',
|
||||
'/pages/user/practice/index',
|
||||
'/pages/user/sop/index',
|
||||
'/pages/user/profile/index'
|
||||
]);
|
||||
|
||||
const goAfterLogin = () => {
|
||||
const redirect = consumeLoginRedirect() || '/pages/user/today/index';
|
||||
if (tabPages.has(redirect)) {
|
||||
uni.switchTab({ url: redirect });
|
||||
return;
|
||||
}
|
||||
uni.redirectTo({ url: redirect });
|
||||
};
|
||||
|
||||
const sendCode = async () => {
|
||||
if (sending.value) return;
|
||||
const value = phone.value.trim();
|
||||
if (!validatePhone(value)) {
|
||||
message.value = '请输入正确手机号';
|
||||
return;
|
||||
}
|
||||
sending.value = true;
|
||||
message.value = '';
|
||||
try {
|
||||
await apiRequest<void>({
|
||||
url: `/resource/sms/code?phonenumber=${encodeURIComponent(value)}`,
|
||||
method: 'GET',
|
||||
auth: false
|
||||
});
|
||||
message.value = '验证码已发送';
|
||||
} catch (error) {
|
||||
message.value = error instanceof Error ? error.message : '验证码发送失败';
|
||||
} finally {
|
||||
sending.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const login = async () => {
|
||||
if (loggingIn.value) return;
|
||||
const value = phone.value.trim();
|
||||
if (!validatePhone(value)) {
|
||||
message.value = '请输入正确手机号';
|
||||
return;
|
||||
}
|
||||
if (!smsCode.value.trim()) {
|
||||
message.value = '请输入短信验证码';
|
||||
return;
|
||||
}
|
||||
loggingIn.value = true;
|
||||
message.value = '';
|
||||
try {
|
||||
const result = await apiRequest<LoginResult>({
|
||||
url: '/auth/mobile/sms-login',
|
||||
method: 'POST',
|
||||
data: {
|
||||
phonenumber: value,
|
||||
smsCode: smsCode.value.trim(),
|
||||
tenantId: '000000'
|
||||
},
|
||||
auth: false
|
||||
});
|
||||
if (!result.access_token || !result.client_id) {
|
||||
throw new Error('登录响应缺少认证信息');
|
||||
}
|
||||
saveAuth(result, value);
|
||||
goAfterLogin();
|
||||
} catch (error) {
|
||||
message.value = error instanceof Error ? error.message : '登录失败';
|
||||
} finally {
|
||||
loggingIn.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onShow(() => {
|
||||
if (isLoggedIn()) {
|
||||
goAfterLogin();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-page {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.login-head {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.code-input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.code-button {
|
||||
width: 112px;
|
||||
flex: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user